Browse Source

Merge branch 'master' into hotfix/3.6

pull/9359/head
Andrew Shvayka 3 years ago
committed by GitHub
parent
commit
2b9575d81a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      application/pom.xml
  2. 1
      application/src/main/data/upgrade/3.6.0/schema_update.sql
  3. 54
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  4. 9
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  5. 3
      application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
  6. 5
      application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java
  7. 5
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java
  8. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetTypesEdgeEventFetcher.java
  9. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java
  10. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetTypesEdgeEventFetcher.java
  11. 16
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  12. 15
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  13. 4
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  14. 3
      application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java
  15. 2
      common/actor/pom.xml
  16. 2
      common/cache/pom.xml
  17. 2
      common/cluster-api/pom.xml
  18. 2
      common/coap-server/pom.xml
  19. 2
      common/dao-api/pom.xml
  20. 9
      common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java
  21. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java
  22. 2
      common/data/pom.xml
  23. 1
      common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java
  24. 4
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageRecordKey.java
  25. 6
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java
  26. 2
      common/data/src/main/java/org/thingsboard/server/common/data/UsageInfo.java
  27. 3
      common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
  28. 22
      common/data/src/main/java/org/thingsboard/server/common/data/widget/DeprecatedFilter.java
  29. 4
      common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java
  30. 7
      common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java
  31. 2
      common/edge-api/pom.xml
  32. 1
      common/edge-api/src/main/proto/edge.proto
  33. 2
      common/message/pom.xml
  34. 2
      common/pom.xml
  35. 2
      common/queue/pom.xml
  36. 2
      common/script/pom.xml
  37. 2
      common/script/remote-js-client/pom.xml
  38. 2
      common/script/script-api/pom.xml
  39. 20
      common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java
  40. 17
      common/script/script-api/src/main/java/org/thingsboard/script/api/js/AbstractJsInvokeService.java
  41. 17
      common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java
  42. 2
      common/stats/pom.xml
  43. 2
      common/transport/coap/pom.xml
  44. 2
      common/transport/http/pom.xml
  45. 2
      common/transport/lwm2m/pom.xml
  46. 2
      common/transport/mqtt/pom.xml
  47. 2
      common/transport/pom.xml
  48. 2
      common/transport/snmp/pom.xml
  49. 2
      common/transport/transport-api/pom.xml
  50. 2
      common/util/pom.xml
  51. 2
      common/version-control/pom.xml
  52. 6
      dao/pom.xml
  53. 6
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  54. 5
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java
  55. 9
      dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java
  56. 34
      dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeInfoEntity.java
  57. 55
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java
  58. 49
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
  59. 134
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeInfoRepository.java
  60. 31
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java
  61. 49
      dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java
  62. 3
      dao/src/main/java/org/thingsboard/server/dao/usage/BasicUsageInfoService.java
  63. 3
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java
  64. 16
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeDao.java
  65. 32
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java
  66. 4
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleDao.java
  67. 16
      dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java
  68. 2
      dao/src/main/resources/sql/schema-entities.sql
  69. 6
      dao/src/main/resources/sql/schema-views-and-functions.sql
  70. 8
      dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceTest.java
  71. 67
      dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java
  72. 137
      dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java
  73. 2
      monitoring/pom.xml
  74. 2
      msa/black-box-tests/pom.xml
  75. 2
      msa/js-executor/package.json
  76. 2
      msa/js-executor/pom.xml
  77. 2
      msa/monitoring/pom.xml
  78. 2
      msa/pom.xml
  79. 2
      msa/tb-node/pom.xml
  80. 2
      msa/tb/pom.xml
  81. 2
      msa/transport/coap/pom.xml
  82. 2
      msa/transport/http/pom.xml
  83. 2
      msa/transport/lwm2m/pom.xml
  84. 2
      msa/transport/mqtt/pom.xml
  85. 2
      msa/transport/pom.xml
  86. 2
      msa/transport/snmp/pom.xml
  87. 2
      msa/vc-executor-docker/pom.xml
  88. 2
      msa/vc-executor/pom.xml
  89. 2
      msa/web-ui/package.json
  90. 2
      msa/web-ui/pom.xml
  91. 4
      netty-mqtt/pom.xml
  92. 8
      pom.xml
  93. 2
      rest-client/pom.xml
  94. 2
      rule-engine/pom.xml
  95. 2
      rule-engine/rule-engine-api/pom.xml
  96. 2
      rule-engine/rule-engine-components/pom.xml
  97. 2
      tools/pom.xml
  98. 2
      transport/coap/pom.xml
  99. 2
      transport/http/pom.xml
  100. 2
      transport/lwm2m/pom.xml

2
application/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>application</artifactId>

1
application/src/main/data/upgrade/3.6.0/schema_update.sql

@ -24,3 +24,4 @@ ALTER TABLE notification DROP CONSTRAINT IF EXISTS fk_notification_request_id;
ALTER TABLE notification DROP CONSTRAINT IF EXISTS fk_notification_recipient_id;
CREATE INDEX IF NOT EXISTS idx_notification_notification_request_id ON notification(request_id);
CREATE INDEX IF NOT EXISTS idx_notification_request_tenant_id ON notification_request(tenant_id);

54
application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java

@ -28,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
@ -36,6 +37,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.security.Authority;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
@ -46,6 +48,8 @@ import org.thingsboard.server.service.entitiy.widgets.type.TbWidgetTypeService;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER;
@ -75,7 +79,11 @@ public class WidgetTypeController extends AutoCommitController {
private static final String WIDGET_TYPE_INFO_DESCRIPTION = "Widget Type Info is a lightweight object that represents Widget Type but does not contain the heavyweight widget descriptor JSON";
private static final String TENANT_ONLY_PARAM_DESCRIPTION = "Optional boolean parameter indicating whether only tenant widget types should be returned";
private static final String FULL_SEARCH_PARAM_DESCRIPTION = "Optional boolean parameter indicating whether search widgets by description not only by name";
private static final String DEPRECATED_FILTER_ALLOWABLE_VALUES = "ALL, ACTUAL, DEPRECATED";
private static final String DEPRECATED_FILTER_PARAM_DESCRIPTION = "Optional string parameter indicating whether to include deprecated widgets";
private static final String UPDATE_EXISTING_BY_FQN_PARAM_DESCRIPTION = "Optional boolean parameter indicating whether to update existing widget type by FQN if present instead of creating new one";
private static final String WIDGET_TYPE_ARRAY_DESCRIPTION = "A list of string values separated by comma ',' representing one of the widget type value";
private static final String WIDGET_TYPE_ALLOWABLE_VALUES = "timeseries, latest, control, alarm, static";
@ApiOperation(value = "Get Widget Type Details (getWidgetTypeById)",
notes = "Get the Widget Type Details based on the provided Widget Type Id. " + WIDGET_TYPE_DETAILS_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@ -166,15 +174,22 @@ public class WidgetTypeController extends AutoCommitController {
@ApiParam(value = TENANT_ONLY_PARAM_DESCRIPTION)
@RequestParam(required = false) Boolean tenantOnly,
@ApiParam(value = FULL_SEARCH_PARAM_DESCRIPTION)
@RequestParam(required = false) Boolean fullSearch) throws ThingsboardException {
@RequestParam(required = false) Boolean fullSearch,
@ApiParam(value = DEPRECATED_FILTER_PARAM_DESCRIPTION, allowableValues = DEPRECATED_FILTER_ALLOWABLE_VALUES)
@RequestParam(required = false) String deprecatedFilter,
@ApiParam(value = WIDGET_TYPE_ARRAY_DESCRIPTION, allowableValues = WIDGET_TYPE_ALLOWABLE_VALUES)
@RequestParam(required = false) String[] widgetTypeList) throws ThingsboardException {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
List<String> widgetTypes = widgetTypeList != null ? Arrays.asList(widgetTypeList) : Collections.emptyList();
boolean fullSearchBool = fullSearch != null && fullSearch;
DeprecatedFilter widgetTypeDeprecatedFilter = StringUtils.isNotEmpty(deprecatedFilter) ? DeprecatedFilter.valueOf(deprecatedFilter) : DeprecatedFilter.ALL;
if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) {
return checkNotNull(widgetTypeService.findSystemWidgetTypesByPageLink(getTenantId(), fullSearch != null && fullSearch, pageLink));
return checkNotNull(widgetTypeService.findSystemWidgetTypesByPageLink(getTenantId(), fullSearchBool, widgetTypeDeprecatedFilter, widgetTypes, pageLink));
} else {
if (tenantOnly != null && tenantOnly) {
return checkNotNull(widgetTypeService.findTenantWidgetTypesByTenantIdAndPageLink(getTenantId(), fullSearch != null && fullSearch, pageLink));
return checkNotNull(widgetTypeService.findTenantWidgetTypesByTenantIdAndPageLink(getTenantId(), fullSearchBool, widgetTypeDeprecatedFilter, widgetTypes, pageLink));
} else {
return checkNotNull(widgetTypeService.findAllTenantWidgetTypesByTenantIdAndPageLink(getTenantId(), fullSearch != null && fullSearch, pageLink));
return checkNotNull(widgetTypeService.findAllTenantWidgetTypesByTenantIdAndPageLink(getTenantId(), fullSearchBool, widgetTypeDeprecatedFilter, widgetTypes, pageLink));
}
}
}
@ -272,19 +287,40 @@ public class WidgetTypeController extends AutoCommitController {
tenantId = getCurrentUser().getTenantId();
}
WidgetsBundle widgetsBundle = checkNotNull(widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(tenantId, bundleAlias));
return checkNotNull(widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(getTenantId(), widgetsBundle.getId()));
return checkNotNull(widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(getTenantId(), widgetsBundle.getId(), false, DeprecatedFilter.ALL,
null, new PageLink(1024))).getData();
}
@ApiOperation(value = "Get Widget Type Info objects (getBundleWidgetTypesInfos)",
notes = "Get the Widget Type Info objects based on the provided parameters. " + WIDGET_TYPE_INFO_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/widgetTypesInfos", params = {"widgetsBundleId"}, method = RequestMethod.GET)
@RequestMapping(value = "/widgetTypesInfos", params = {"widgetsBundleId", "pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public List<WidgetTypeInfo> getBundleWidgetTypesInfos(
public PageData<WidgetTypeInfo> getBundleWidgetTypesInfos(
@ApiParam(value = "Widget Bundle Id", required = true)
@RequestParam("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException {
@RequestParam("widgetsBundleId") String strWidgetsBundleId,
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
@RequestParam int page,
@ApiParam(value = WIDGET_TYPE_TEXT_SEARCH_DESCRIPTION)
@RequestParam(required = false) String textSearch,
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = WIDGET_TYPE_SORT_PROPERTY_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder,
@ApiParam(value = FULL_SEARCH_PARAM_DESCRIPTION)
@RequestParam(required = false) Boolean fullSearch,
@ApiParam(value = DEPRECATED_FILTER_PARAM_DESCRIPTION, allowableValues = DEPRECATED_FILTER_ALLOWABLE_VALUES)
@RequestParam(required = false) String deprecatedFilter,
@ApiParam(value = WIDGET_TYPE_ARRAY_DESCRIPTION, allowableValues = WIDGET_TYPE_ALLOWABLE_VALUES)
@RequestParam(required = false) String[] widgetTypeList) throws ThingsboardException {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
return checkNotNull(widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(getTenantId(), widgetsBundleId));
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
List<String> widgetTypes = widgetTypeList != null ? Arrays.asList(widgetTypeList) : Collections.emptyList();
DeprecatedFilter widgetTypeDeprecatedFilter = StringUtils.isNotEmpty(deprecatedFilter) ? DeprecatedFilter.valueOf(deprecatedFilter) : DeprecatedFilter.ALL;
return checkNotNull(widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(getTenantId(), widgetsBundleId, fullSearch != null && fullSearch,
widgetTypeDeprecatedFilter, widgetTypes, pageLink));
}
@ApiOperation(value = "Get Widget Type (getWidgetTypeByBundleAliasAndTypeAlias) (Deprecated)",

9
application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java

@ -68,6 +68,7 @@ public class WidgetsBundleController extends BaseController {
private final TbWidgetsBundleService tbWidgetsBundleService;
private static final String WIDGET_BUNDLE_DESCRIPTION = "Widget Bundle represents a group(bundle) of widgets. Widgets are grouped into bundle by type or use case. ";
private static final String FULL_SEARCH_PARAM_DESCRIPTION = "Optional boolean parameter indicating extended search of widget bundles by description and by name / description of related widget types";
@ApiOperation(value = "Get Widget Bundle (getWidgetsBundleById)",
notes = "Get the Widget Bundle based on the provided Widget Bundle Id. " + WIDGET_BUNDLE_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
@ -183,13 +184,15 @@ public class WidgetsBundleController extends BaseController {
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = WIDGET_BUNDLE_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 {
@RequestParam(required = false) String sortOrder,
@ApiParam(value = FULL_SEARCH_PARAM_DESCRIPTION)
@RequestParam(required = false) Boolean fullSearch) throws ThingsboardException {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) {
return checkNotNull(widgetsBundleService.findSystemWidgetsBundlesByPageLink(getTenantId(), pageLink));
return checkNotNull(widgetsBundleService.findSystemWidgetsBundlesByPageLink(getTenantId(), fullSearch != null && fullSearch, pageLink));
} else {
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink));
return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, fullSearch != null && fullSearch, pageLink));
}
}

3
application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java

@ -262,6 +262,9 @@ public class ThingsboardInstallService {
databaseEntitiesUpgradeService.upgradeDatabase("3.5.1");
dataUpdateService.updateData("3.5.1");
systemDataLoaderService.updateDefaultNotificationConfigs();
case "3.6.0":
log.info("Upgrading ThingsBoard from version 3.6.0 to 3.6.1 ...");
databaseEntitiesUpgradeService.upgradeDatabase("3.6.0");
//TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache
break;
default:

5
application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java

@ -145,6 +145,8 @@ public abstract class BaseApiUsageState {
return apiUsageState.getDbStorageState();
case JS:
return apiUsageState.getJsExecState();
case TBEL:
return apiUsageState.getTbelExecState();
case EMAIL:
return apiUsageState.getEmailExecState();
case SMS:
@ -171,6 +173,9 @@ public abstract class BaseApiUsageState {
case JS:
apiUsageState.setJsExecState(value);
break;
case TBEL:
apiUsageState.setTbelExecState(value);
break;
case EMAIL:
apiUsageState.setEmailExecState(value);
break;

5
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java

@ -24,6 +24,8 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.Arrays;
@Component
@TbCoreComponent
public class WidgetTypeMsgConstructor {
@ -59,6 +61,9 @@ public class WidgetTypeMsgConstructor {
builder.setDescription(widgetTypeDetails.getDescription());
}
builder.setDeprecated(widgetTypeDetails.isDeprecated());
if (widgetTypeDetails.getTags() != null) {
builder.addAllTags(Arrays.asList(widgetTypeDetails.getTags()));
}
return builder.build();
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetTypesEdgeEventFetcher.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.dao.widget.WidgetTypeService;
@ -31,6 +32,6 @@ public class SystemWidgetTypesEdgeEventFetcher extends BaseWidgetTypesEdgeEventF
@Override
protected PageData<WidgetTypeInfo> findWidgetTypes(TenantId tenantId, PageLink pageLink) {
return widgetTypeService.findSystemWidgetTypesByPageLink(tenantId, false, pageLink);
return widgetTypeService.findSystemWidgetTypesByPageLink(tenantId, false, DeprecatedFilter.ALL, null, pageLink);
}
}

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/SystemWidgetsBundlesEdgeEventFetcher.java

@ -31,6 +31,6 @@ public class SystemWidgetsBundlesEdgeEventFetcher extends BaseWidgetsBundlesEdge
@Override
protected PageData<WidgetsBundle> findWidgetsBundles(TenantId tenantId, PageLink pageLink) {
return widgetsBundleService.findSystemWidgetsBundlesByPageLink(tenantId, pageLink);
return widgetsBundleService.findSystemWidgetsBundlesByPageLink(tenantId, false, pageLink);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantWidgetTypesEdgeEventFetcher.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.dao.widget.WidgetTypeService;
@ -30,6 +31,6 @@ public class TenantWidgetTypesEdgeEventFetcher extends BaseWidgetTypesEdgeEventF
}
@Override
protected PageData<WidgetTypeInfo> findWidgetTypes(TenantId tenantId, PageLink pageLink) {
return widgetTypeService.findTenantWidgetTypesByTenantIdAndPageLink(tenantId, false, pageLink);
return widgetTypeService.findTenantWidgetTypesByTenantIdAndPageLink(tenantId, false, DeprecatedFilter.ALL, null, pageLink);
}
}

16
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java

@ -63,6 +63,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.BooleanDataEntry;
import org.thingsboard.server.common.data.kv.DoubleDataEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.query.BooleanFilterPredicate;
@ -83,6 +84,8 @@ import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.customer.CustomerService;
@ -489,10 +492,15 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
public void deleteSystemWidgetBundle(String bundleAlias) throws Exception {
WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(TenantId.SYS_TENANT_ID, bundleAlias);
if (widgetsBundle != null) {
var widgetTypes = widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(TenantId.SYS_TENANT_ID, widgetsBundle.getId());
for (var widgetType : widgetTypes) {
widgetTypeService.deleteWidgetType(TenantId.SYS_TENANT_ID, widgetType.getId());
}
PageData<WidgetTypeInfo> widgetTypes;
var pageLink = new PageLink(1024);
do {
widgetTypes = widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(TenantId.SYS_TENANT_ID, widgetsBundle.getId(), false, DeprecatedFilter.ALL, null, pageLink);
for (var widgetType : widgetTypes.getData()) {
widgetTypeService.deleteWidgetType(TenantId.SYS_TENANT_ID, widgetType.getId());
}
pageLink.nextPageLink();
} while (widgetTypes.hasNext());
widgetsBundleService.deleteWidgetsBundle(TenantId.SYS_TENANT_ID, widgetsBundle.getId());
}
}

15
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -777,6 +777,21 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
log.error("Failed updating schema!!!", e);
}
break;
case "3.6.0":
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
if (isOldSchema(conn, 3006000)) {
log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.0", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn);
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3006001;");
log.info("Schema updated to version 3.6.1.");
} else {
log.info("Skip schema re-update to version 3.6.1. Use env flag 'SKIP_SCHEMA_VERSION_CHECK' to force the re-update.");
}
} catch (Exception e) {
log.error("Failed updating schema!!!", e);
}
break;
default:
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
}

4
application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java

@ -362,6 +362,8 @@ public class DefaultMailService implements MailService {
return valueInM + " out of " + thresholdInM + " allowed messages";
case JS_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed JavaScript functions";
case TBEL_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed Tbel functions";
case RE_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed Rule Engine messages";
case EMAIL_EXEC_COUNT:
@ -382,6 +384,8 @@ public class DefaultMailService implements MailService {
return recordState.getValueAsString() + " messages";
case JS_EXEC_COUNT:
return "JavaScript functions " + recordState.getValueAsString() + " times";
case TBEL_EXEC_COUNT:
return "TBEL functions " + recordState.getValueAsString() + " times";
case RE_EXEC_COUNT:
return recordState.getValueAsString() + " Rule Engine messages";
case EMAIL_EXEC_COUNT:

3
application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java

@ -417,6 +417,9 @@ public class HomePageApiTest extends AbstractControllerTest {
Assert.assertEquals(0, usageInfo.getJsExecutions());
Assert.assertEquals(configuration.getMaxJSExecutions(), usageInfo.getMaxJsExecutions());
Assert.assertEquals(0, usageInfo.getTbelExecutions());
Assert.assertEquals(configuration.getMaxTbelExecutions(), usageInfo.getMaxTbelExecutions());
Assert.assertEquals(0, usageInfo.getEmails());
Assert.assertEquals(configuration.getMaxEmails(), usageInfo.getMaxEmails());

2
common/actor/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/cache/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/cluster-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/coap-server/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/dao-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

9
common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java

@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.id.WidgetTypeId;
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.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
@ -39,17 +40,17 @@ public interface WidgetTypeService extends EntityDaoService {
void deleteWidgetType(TenantId tenantId, WidgetTypeId widgetTypeId);
PageData<WidgetTypeInfo> findSystemWidgetTypesByPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findSystemWidgetTypesByPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
List<WidgetType> findWidgetTypesByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId);
List<WidgetTypeDetails> findWidgetTypesDetailsByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId);
List<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId);
PageData<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
List<String> findWidgetFqnsByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId);

4
common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java

@ -34,13 +34,13 @@ public interface WidgetsBundleService extends EntityDaoService {
WidgetsBundle findWidgetsBundleByTenantIdAndAlias(TenantId tenantId, String alias);
PageData<WidgetsBundle> findSystemWidgetsBundlesByPageLink(TenantId tenantId, PageLink pageLink);
PageData<WidgetsBundle> findSystemWidgetsBundlesByPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink);
List<WidgetsBundle> findSystemWidgetsBundles(TenantId tenantId);
PageData<WidgetsBundle> findTenantWidgetsBundlesByTenantId(TenantId tenantId, PageLink pageLink);
PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantIdAndPageLink(TenantId tenantId, PageLink pageLink);
PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink);
List<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(TenantId tenantId);

2
common/data/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

1
common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java

@ -22,6 +22,7 @@ public enum ApiFeature {
DB("dbApiState", "Telemetry persistence"),
RE("ruleEngineApiState", "Rule Engine execution"),
JS("jsExecutionApiState", "JavaScript functions execution"),
TBEL("tbelExecutionApiState", "Tbel functions execution"),
EMAIL("emailApiState", "Email messages"),
SMS("smsApiState", "SMS messages"),
ALARM("alarmApiState", "Alarms");

4
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageRecordKey.java

@ -24,6 +24,7 @@ public enum ApiUsageRecordKey {
STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit", "data point"),
RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit", "Rule Engine execution"),
JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit", "JavaScript execution"),
TBEL_EXEC_COUNT(ApiFeature.TBEL, "tbelExecutionCount", "tbelExecutionLimit", "Tbel execution"),
EMAIL_EXEC_COUNT(ApiFeature.EMAIL, "emailCount", "emailLimit", "email message"),
SMS_EXEC_COUNT(ApiFeature.SMS, "smsCount", "smsLimit", "SMS message"),
CREATED_ALARMS_COUNT(ApiFeature.ALARM, "createdAlarmsCount", "createdAlarmsLimit", "alarm"),
@ -31,6 +32,7 @@ public enum ApiUsageRecordKey {
INACTIVE_DEVICES("inactiveDevicesCount");
private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT};
private static final ApiUsageRecordKey[] TBEL_RECORD_KEYS = {TBEL_EXEC_COUNT};
private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_EXEC_COUNT};
private static final ApiUsageRecordKey[] DB_RECORD_KEYS = {STORAGE_DP_COUNT};
private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT};
@ -75,6 +77,8 @@ public enum ApiUsageRecordKey {
return RE_RECORD_KEYS;
case JS:
return JS_RECORD_KEYS;
case TBEL:
return TBEL_RECORD_KEYS;
case EMAIL:
return EMAIL_RECORD_KEYS;
case SMS:

6
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java

@ -37,6 +37,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
private ApiUsageStateValue dbStorageState;
private ApiUsageStateValue reExecState;
private ApiUsageStateValue jsExecState;
private ApiUsageStateValue tbelExecState;
private ApiUsageStateValue emailExecState;
private ApiUsageStateValue smsExecState;
private ApiUsageStateValue alarmExecState;
@ -57,6 +58,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState();
this.tbelExecState = ur.getTbelExecState();
this.emailExecState = ur.getEmailExecState();
this.smsExecState = ur.getSmsExecState();
this.alarmExecState = ur.getAlarmExecState();
@ -78,6 +80,10 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
return !ApiUsageStateValue.DISABLED.equals(jsExecState);
}
public boolean isTbelExecEnabled() {
return !ApiUsageStateValue.DISABLED.equals(tbelExecState);
}
public boolean isEmailSendEnabled(){
return !ApiUsageStateValue.DISABLED.equals(emailExecState);
}

2
common/data/src/main/java/org/thingsboard/server/common/data/UsageInfo.java

@ -33,7 +33,9 @@ public class UsageInfo {
private long transportMessages;
private long maxTransportMessages;
private long jsExecutions;
private long tbelExecutions;
private long maxJsExecutions;
private long maxTbelExecutions;
private long emails;
private long maxEmails;
private long sms;

3
common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java

@ -56,6 +56,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
private long maxTransportDataPoints;
private long maxREExecutions;
private long maxJSExecutions;
private long maxTbelExecutions;
private long maxDPStorageDays;
private int maxRuleNodeExecutionsPerMessage;
private long maxEmails;
@ -96,6 +97,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
return maxTransportDataPoints;
case JS_EXEC_COUNT:
return maxJSExecutions;
case TBEL_EXEC_COUNT:
return maxTbelExecutions;
case RE_EXEC_COUNT:
return maxREExecutions;
case STORAGE_DP_COUNT:

22
common/data/src/main/java/org/thingsboard/server/common/data/widget/DeprecatedFilter.java

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.widget;
public enum DeprecatedFilter {
ALL,
ACTUAL,
DEPRECATED
}

4
common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java

@ -38,6 +38,9 @@ public class WidgetTypeDetails extends WidgetType implements HasName, HasTenantI
@Length(fieldName = "description", max = 1024)
@ApiModelProperty(position = 10, value = "Description of the widget")
private String description;
@NoXss
@ApiModelProperty(position = 11, value = "Tags of the widget type")
private String[] tags;
@Getter
@Setter
@ -59,6 +62,7 @@ public class WidgetTypeDetails extends WidgetType implements HasName, HasTenantI
super(widgetTypeDetails);
this.image = widgetTypeDetails.getImage();
this.description = widgetTypeDetails.getDescription();
this.tags = widgetTypeDetails.getTags();
this.externalId = widgetTypeDetails.getExternalId();
}
}

7
common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java

@ -29,7 +29,10 @@ public class WidgetTypeInfo extends BaseWidgetType {
@ApiModelProperty(position = 9, value = "Description of the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private String description;
@NoXss
@ApiModelProperty(position = 10, value = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
@ApiModelProperty(position = 10, value = "Tags of the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private String[] tags;
@NoXss
@ApiModelProperty(position = 11, value = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private String widgetType;
public WidgetTypeInfo() {
@ -48,6 +51,7 @@ public class WidgetTypeInfo extends BaseWidgetType {
super(widgetTypeInfo);
this.image = widgetTypeInfo.getImage();
this.description = widgetTypeInfo.getDescription();
this.tags = widgetTypeInfo.getTags();
this.widgetType = widgetTypeInfo.getWidgetType();
}
@ -55,6 +59,7 @@ public class WidgetTypeInfo extends BaseWidgetType {
super(widgetTypeDetails);
this.image = widgetTypeDetails.getImage();
this.description = widgetTypeDetails.getDescription();
this.tags = widgetTypeDetails.getTags();
if (widgetTypeDetails.getDescriptor() != null && widgetTypeDetails.getDescriptor().has("type")) {
this.widgetType = widgetTypeDetails.getDescriptor().get("type").asText();
} else {

2
common/edge-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

1
common/edge-api/src/main/proto/edge.proto

@ -377,6 +377,7 @@ message WidgetTypeUpdateMsg {
optional string description = 10;
optional string fqn = 11;
bool deprecated = 12;
repeated string tags = 13;
}
message AdminSettingsUpdateMsg {

2
common/message/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>common</artifactId>

2
common/queue/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/script/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/script/remote-js-client/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>script</artifactId>
</parent>
<groupId>org.thingsboard.common.script</groupId>

2
common/script/script-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>script</artifactId>
</parent>
<groupId>org.thingsboard.common.script</groupId>

20
common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java

@ -25,11 +25,8 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@ -45,9 +42,6 @@ import static java.lang.String.format;
public abstract class AbstractScriptInvokeService implements ScriptInvokeService {
protected final Map<UUID, BlockedScriptInfo> disabledScripts = new ConcurrentHashMap<>();
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
private final AtomicInteger pushedMsgs = new AtomicInteger(0);
private final AtomicInteger invokeMsgs = new AtomicInteger(0);
private final AtomicInteger evalMsgs = new AtomicInteger(0);
@ -59,11 +53,6 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
protected ScheduledExecutorService timeoutExecutorService;
protected AbstractScriptInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
}
protected long getMaxEvalRequestsTimeout() {
return getMaxInvokeRequestsTimeout();
}
@ -88,6 +77,9 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
protected abstract boolean isScriptPresent(UUID scriptId);
protected abstract boolean isExecEnabled(TenantId tenantId);
protected abstract void reportExecution(TenantId tenantId, CustomerId customerId);
protected abstract ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames);
protected abstract TbScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args);
@ -122,7 +114,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
@Override
public ListenableFuture<UUID> eval(TenantId tenantId, ScriptType scriptType, String scriptBody, String... argNames) {
if (!apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled()) {
if (isExecEnabled(tenantId)) {
if (scriptBodySizeExceeded(scriptBody)) {
return error(format("Script body exceeds maximum allowed size of %s symbols", getMaxScriptBodySize()));
}
@ -137,7 +129,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
@Override
public ListenableFuture<Object> invokeScript(TenantId tenantId, CustomerId customerId, UUID scriptId, Object... args) {
if (!apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled()) {
if (isExecEnabled(tenantId)) {
if (!isScriptPresent(scriptId)) {
return error("No compiled script found for scriptId: [" + scriptId + "]!");
}
@ -148,7 +140,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
));
return Futures.immediateFailedFuture(handleScriptException(scriptId, null, t));
}
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.JS_EXEC_COUNT, 1));
reportExecution(tenantId, customerId);
pushedMsgs.incrementAndGet();
log.trace("[{}] InvokeScript uuid {} with timeout {}ms", tenantId, scriptId, getMaxInvokeRequestsTimeout());
var task = doInvokeFunction(scriptId, args);

17
common/script/script-api/src/main/java/org/thingsboard/script/api/js/AbstractJsInvokeService.java

@ -23,6 +23,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.thingsboard.script.api.AbstractScriptInvokeService;
import org.thingsboard.script.api.RuleNodeScriptFactory;
import org.thingsboard.script.api.ScriptType;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient;
@ -39,6 +41,8 @@ import java.util.concurrent.ConcurrentHashMap;
public abstract class AbstractJsInvokeService extends AbstractScriptInvokeService implements JsInvokeService {
protected final Map<UUID, JsScriptInfo> scriptInfoMap = new ConcurrentHashMap<>();
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
@Getter
@Value("${js.max_total_args_size:100000}")
@ -51,7 +55,8 @@ public abstract class AbstractJsInvokeService extends AbstractScriptInvokeServic
private long maxScriptBodySize;
protected AbstractJsInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
super(apiUsageStateClient, apiUsageReportClient);
this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
}
@Override
@ -59,6 +64,16 @@ public abstract class AbstractJsInvokeService extends AbstractScriptInvokeServic
return scriptInfoMap.containsKey(scriptId);
}
@Override
protected boolean isExecEnabled(TenantId tenantId) {
return !apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled();
}
@Override
protected void reportExecution(TenantId tenantId, CustomerId customerId) {
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.JS_EXEC_COUNT, 1));
}
@Override
protected JsScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args) {
return new JsScriptExecutionTask(doInvokeFunction(scriptId, scriptInfoMap.get(scriptId), args));

17
common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java

@ -40,6 +40,8 @@ import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.script.api.AbstractScriptInvokeService;
import org.thingsboard.script.api.ScriptType;
import org.thingsboard.script.api.TbScriptException;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient;
@ -69,6 +71,8 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
protected Cache<String, Serializable> compiledScriptsCache;
private SandboxedParserConfiguration parserConfig;
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
@Getter
@Value("${tbel.max_total_args_size:100000}")
@ -110,7 +114,8 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
private final Lock lock = new ReentrantLock();
protected DefaultTbelInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
super(apiUsageStateClient, apiUsageReportClient);
this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
}
@Scheduled(fixedDelayString = "${tbel.stats.print_interval_ms:10000}")
@ -167,6 +172,16 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
return scriptIdToHash.containsKey(scriptId);
}
@Override
protected boolean isExecEnabled(TenantId tenantId) {
return !apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isTbelExecEnabled();
}
@Override
protected void reportExecution(TenantId tenantId, CustomerId customerId) {
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.TBEL_EXEC_COUNT, 1));
}
@Override
protected ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames) {
return executor.submit(() -> {

2
common/stats/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>

2
common/transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>

2
common/transport/lwm2m/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>

2
common/transport/mqtt/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>

2
common/transport/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/transport/snmp/pom.xml

@ -21,7 +21,7 @@
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>

2
common/transport/transport-api/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>

2
common/util/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

2
common/version-control/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>common</artifactId>
</parent>
<groupId>org.thingsboard.common</groupId>

6
dao/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>dao</artifactId>
@ -230,6 +230,10 @@
<groupId>org.thingsboard.rule-engine</groupId>
<artifactId>rule-engine-api</artifactId>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-55</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

6
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -313,10 +313,15 @@ public class ModelConstants {
public static final String WIDGET_TYPE_NAME_PROPERTY = "name";
public static final String WIDGET_TYPE_IMAGE_PROPERTY = "image";
public static final String WIDGET_TYPE_DESCRIPTION_PROPERTY = "description";
public static final String WIDGET_TYPE_TAGS_PROPERTY = "tags";
public static final String WIDGET_TYPE_DESCRIPTOR_PROPERTY = "descriptor";
public static final String WIDGET_TYPE_DEPRECATED_PROPERTY = "deprecated";
public static final String WIDGET_TYPE_WIDGET_TYPE_PROPERTY = "widget_type";
public static final String WIDGET_TYPE_INFO_VIEW_TABLE_NAME = "widget_type_info_view";
/**
* Widgets bundle widget constants.
*/
@ -477,6 +482,7 @@ public class ModelConstants {
public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage";
public static final String API_USAGE_STATE_RE_EXEC_COLUMN = "re_exec";
public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec";
public static final String API_USAGE_STATE_TBEL_EXEC_COLUMN = "tbel_exec";
public static final String API_USAGE_STATE_EMAIL_EXEC_COLUMN = "email_exec";
public static final String API_USAGE_STATE_SMS_EXEC_COLUMN = "sms_exec";
public static final String API_USAGE_STATE_ALARM_EXEC_COLUMN = "alarm_exec";

5
dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java

@ -64,6 +64,9 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
@Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN)
private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_TBEL_EXEC_COLUMN)
private ApiUsageStateValue tbelExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_EMAIL_EXEC_COLUMN)
private ApiUsageStateValue emailExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@ -92,6 +95,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState();
this.tbelExecState = ur.getTbelExecState();
this.emailExecState = ur.getEmailExecState();
this.smsExecState = ur.getSmsExecState();
this.alarmExecState = ur.getAlarmExecState();
@ -111,6 +115,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
ur.setDbStorageState(dbStorageState);
ur.setReExecState(reExecState);
ur.setJsExecState(jsExecState);
ur.setTbelExecState(tbelExecState);
ur.setEmailExecState(emailExecState);
ur.setSmsExecState(smsExecState);
ur.setAlarmExecState(alarmExecState);

9
dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java

@ -16,12 +16,12 @@
package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.array.StringArrayType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.widget.BaseWidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.dao.model.ModelConstants;
@ -36,6 +36,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@TypeDef(name = "string-array", typeClass = StringArrayType.class)
@Table(name = ModelConstants.WIDGET_TYPE_TABLE_NAME)
public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity<WidgetTypeDetails> {
@ -45,6 +46,10 @@ public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity<WidgetType
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTION_PROPERTY)
private String description;
@Type(type="string-array")
@Column(name = ModelConstants.WIDGET_TYPE_TAGS_PROPERTY, columnDefinition = "text[]")
private String[] tags;
@Type(type="json")
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
private JsonNode descriptor;
@ -60,6 +65,7 @@ public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity<WidgetType
super(widgetTypeDetails);
this.image = widgetTypeDetails.getImage();
this.description = widgetTypeDetails.getDescription();
this.tags = widgetTypeDetails.getTags();
this.descriptor = widgetTypeDetails.getDescriptor();
if (widgetTypeDetails.getExternalId() != null) {
this.externalId = widgetTypeDetails.getExternalId().getId();
@ -72,6 +78,7 @@ public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity<WidgetType
WidgetTypeDetails widgetTypeDetails = new WidgetTypeDetails(baseWidgetType);
widgetTypeDetails.setImage(image);
widgetTypeDetails.setDescription(description);
widgetTypeDetails.setTags(tags);
widgetTypeDetails.setDescriptor(descriptor);
if (externalId != null) {
widgetTypeDetails.setExternalId(new WidgetTypeId(externalId));

34
dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeInfoEntity.java

@ -15,40 +15,52 @@
*/
package org.thingsboard.server.dao.model.sql;
import io.hypersistence.utils.hibernate.type.array.StringArrayType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.widget.BaseWidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.dao.model.ModelConstants;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Immutable
@TypeDef(name = "string-array", typeClass = StringArrayType.class)
@Table(name = ModelConstants.WIDGET_TYPE_INFO_VIEW_TABLE_NAME)
public final class WidgetTypeInfoEntity extends AbstractWidgetTypeEntity<WidgetTypeInfo> {
@Column(name = ModelConstants.WIDGET_TYPE_IMAGE_PROPERTY)
private String image;
@Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTION_PROPERTY)
private String description;
@Type(type="string-array")
@Column(name = ModelConstants.WIDGET_TYPE_TAGS_PROPERTY, columnDefinition = "text[]")
private String[] tags;
@Column(name = ModelConstants.WIDGET_TYPE_WIDGET_TYPE_PROPERTY)
private String widgetType;
public WidgetTypeInfoEntity() {
super();
}
public WidgetTypeInfoEntity(WidgetTypeDetailsEntity widgetTypeDetailsEntity) {
super(widgetTypeDetailsEntity);
this.image = widgetTypeDetailsEntity.getImage();
this.description = widgetTypeDetailsEntity.getDescription();
if (widgetTypeDetailsEntity.getDescriptor() != null && widgetTypeDetailsEntity.getDescriptor().has("type")) {
this.widgetType = widgetTypeDetailsEntity.getDescriptor().get("type").asText();
} else {
this.widgetType = "";
}
}
@Override
public WidgetTypeInfo toData() {
BaseWidgetType baseWidgetType = super.toBaseWidgetType();
WidgetTypeInfo widgetTypeInfo = new WidgetTypeInfo(baseWidgetType);
widgetTypeInfo.setImage(image);
widgetTypeInfo.setDescription(description);
widgetTypeInfo.setTags(tags);
widgetTypeInfo.setWidgetType(widgetType);
return widgetTypeInfo;
}

55
dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
@ -35,6 +36,7 @@ import org.thingsboard.server.dao.sql.JpaAbstractDao;
import org.thingsboard.server.dao.util.SqlDao;
import org.thingsboard.server.dao.widget.WidgetTypeDao;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
@ -54,6 +56,9 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeDetailsEntity, Wi
@Autowired
private WidgetTypeRepository widgetTypeRepository;
@Autowired
private WidgetTypeInfoRepository widgetTypeInfoRepository;
@Autowired
private WidgetsBundleWidgetRepository widgetsBundleWidgetRepository;
@ -78,36 +83,57 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeDetailsEntity, Wi
}
@Override
public PageData<WidgetTypeInfo> findSystemWidgetTypes(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
public PageData<WidgetTypeInfo> findSystemWidgetTypes(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
boolean deprecatedFilterEnabled = !DeprecatedFilter.ALL.equals(deprecatedFilter);
boolean deprecatedFilterBool = DeprecatedFilter.DEPRECATED.equals(deprecatedFilter);
boolean widgetTypesEmpty = widgetTypes == null || widgetTypes.isEmpty();
return DaoUtil.toPageData(
widgetTypeRepository
widgetTypeInfoRepository
.findSystemWidgetTypes(
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
fullSearch,
deprecatedFilterEnabled,
deprecatedFilterBool,
widgetTypesEmpty,
widgetTypes == null ? Collections.emptyList() : widgetTypes,
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink) {
public PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
boolean deprecatedFilterEnabled = !DeprecatedFilter.ALL.equals(deprecatedFilter);
boolean deprecatedFilterBool = DeprecatedFilter.DEPRECATED.equals(deprecatedFilter);
boolean widgetTypesEmpty = widgetTypes == null || widgetTypes.isEmpty();
return DaoUtil.toPageData(
widgetTypeRepository
widgetTypeInfoRepository
.findAllTenantWidgetTypesByTenantId(
tenantId,
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
fullSearch,
deprecatedFilterEnabled,
deprecatedFilterBool,
widgetTypesEmpty,
widgetTypes == null ? Collections.emptyList() : widgetTypes,
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink) {
public PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
boolean deprecatedFilterEnabled = !DeprecatedFilter.ALL.equals(deprecatedFilter);
boolean deprecatedFilterBool = DeprecatedFilter.DEPRECATED.equals(deprecatedFilter);
boolean widgetTypesEmpty = widgetTypes == null || widgetTypes.isEmpty();
return DaoUtil.toPageData(
widgetTypeRepository
widgetTypeInfoRepository
.findTenantWidgetTypesByTenantId(
tenantId,
Objects.toString(pageLink.getTextSearch(), ""),
fullSearch,
deprecatedFilterEnabled,
deprecatedFilterBool,
widgetTypesEmpty,
widgetTypes == null ? Collections.emptyList() : widgetTypes,
DaoUtil.toPageable(pageLink)));
}
@ -122,8 +148,21 @@ public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeDetailsEntity, Wi
}
@Override
public List<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId) {
return DaoUtil.convertDataList(widgetTypeRepository.findWidgetTypesInfosByWidgetsBundleId(widgetsBundleId));
public PageData<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
boolean deprecatedFilterEnabled = !DeprecatedFilter.ALL.equals(deprecatedFilter);
boolean deprecatedFilterBool = DeprecatedFilter.DEPRECATED.equals(deprecatedFilter);
boolean widgetTypesEmpty = widgetTypes == null || widgetTypes.isEmpty();
return DaoUtil.toPageData(
widgetTypeInfoRepository
.findWidgetTypesInfosByWidgetsBundleId(
widgetsBundleId,
Objects.toString(pageLink.getTextSearch(), ""),
fullSearch,
deprecatedFilterEnabled,
deprecatedFilterBool,
widgetTypesEmpty,
widgetTypes == null ? Collections.emptyList() : widgetTypes,
DaoUtil.toPageable(pageLink)));
}
@Override

49
dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java

@ -62,13 +62,22 @@ public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, Wid
}
@Override
public PageData<WidgetsBundle> findSystemWidgetsBundles(TenantId tenantId, PageLink pageLink) {
return DaoUtil.toPageData(
widgetsBundleRepository
.findSystemWidgetsBundles(
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
public PageData<WidgetsBundle> findSystemWidgetsBundles(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
if (fullSearch) {
return DaoUtil.toPageData(
widgetsBundleRepository
.findSystemWidgetsBundlesFullSearch(
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
} else {
return DaoUtil.toPageData(
widgetsBundleRepository
.findSystemWidgetsBundles(
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
}
@Override
@ -82,14 +91,24 @@ public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, Wid
}
@Override
public PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(
widgetsBundleRepository
.findAllTenantWidgetsBundlesByTenantId(
tenantId,
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
public PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink) {
if (fullSearch) {
return DaoUtil.toPageData(
widgetsBundleRepository
.findAllTenantWidgetsBundlesByTenantIdFullSearch(
tenantId,
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
} else {
return DaoUtil.toPageData(
widgetsBundleRepository
.findAllTenantWidgetsBundlesByTenantId(
tenantId,
NULL_UUID,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
}
@Override

134
dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeInfoRepository.java

@ -0,0 +1,134 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.sql.widget;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity;
import java.util.List;
import java.util.UUID;
public interface WidgetTypeInfoRepository extends JpaRepository<WidgetTypeInfoEntity, UUID> {
@Query(nativeQuery = true,
value = "SELECT * FROM widget_type_info_view wti WHERE wti.tenant_id = :systemTenantId " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))",
// "OR to_tsvector(lower(array_to_string(wti.tags, ' '))) @@ to_tsquery(lower(:searchText)))))",
countQuery = "SELECT count(*) FROM widget_type_info_view wti WHERE wti.tenant_id = :systemTenantId " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))"
)
Page<WidgetTypeInfoEntity> findSystemWidgetTypes(@Param("systemTenantId") UUID systemTenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
@Param("deprecatedFilterEnabled") boolean deprecatedFilterEnabled,
@Param("deprecatedFilter") boolean deprecatedFilter,
@Param("widgetTypesEmpty") boolean widgetTypesEmpty,
@Param("widgetTypes") List<String> widgetTypes,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT * FROM widget_type_info_view wti WHERE wti.tenant_id IN (:tenantId, :nullTenantId) " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))",
countQuery = "SELECT count(*) FROM widget_type_info_view wti WHERE wti.tenant_id IN (:tenantId, :nullTenantId) " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))"
)
Page<WidgetTypeInfoEntity> findAllTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
@Param("nullTenantId") UUID nullTenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
@Param("deprecatedFilterEnabled") boolean deprecatedFilterEnabled,
@Param("deprecatedFilter") boolean deprecatedFilter,
@Param("widgetTypesEmpty") boolean widgetTypesEmpty,
@Param("widgetTypes") List<String> widgetTypes,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT * FROM widget_type_info_view wti WHERE wti.tenant_id = :tenantId " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))",
countQuery = "SELECT count(*) FROM widget_type_info_view wti WHERE wti.tenant_id = :tenantId " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))"
)
Page<WidgetTypeInfoEntity> findTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
@Param("deprecatedFilterEnabled") boolean deprecatedFilterEnabled,
@Param("deprecatedFilter") boolean deprecatedFilter,
@Param("widgetTypesEmpty") boolean widgetTypesEmpty,
@Param("widgetTypes") List<String> widgetTypes,
Pageable pageable);
@Query("SELECT wti FROM WidgetTypeInfoEntity wti, WidgetsBundleWidgetEntity wbw " +
"WHERE wbw.widgetsBundleId = :widgetsBundleId " +
"AND wbw.widgetTypeId = wti.id ORDER BY wbw.widgetTypeOrder")
List<WidgetTypeInfoEntity> findWidgetTypesInfosByWidgetsBundleId(@Param("widgetsBundleId") UUID widgetsBundleId);
@Query(nativeQuery = true,
value = "SELECT * FROM widget_type_info_view wti, widgets_bundle_widget wbw " +
"WHERE wbw.widgets_bundle_id = :widgetsBundleId " +
"AND wbw.widget_type_id = wti.id " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' ')))) " +
"ORDER BY wbw.widget_type_order",
countQuery = "SELECT count(*) FROM widget_type_info_view wti, widgets_bundle_widget wbw " +
"WHERE wbw.widgets_bundle_id = :widgetsBundleId " +
"AND wbw.widget_type_id = wti.id " +
"AND ((:deprecatedFilterEnabled) IS FALSE OR wti.deprecated = :deprecatedFilter) " +
"AND ((:widgetTypesEmpty) IS TRUE OR wti.widget_type IN (:widgetTypes)) " +
"AND (wti.name ILIKE CONCAT('%', :searchText, '%') " +
"OR ((:fullSearch) IS TRUE AND (wti.description ILIKE CONCAT('%', :searchText, '%') " +
"OR lower(wti.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:searchText), ' '))))"
)
Page<WidgetTypeInfoEntity> findWidgetTypesInfosByWidgetsBundleId(@Param("widgetsBundleId") UUID widgetsBundleId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
@Param("deprecatedFilterEnabled") boolean deprecatedFilterEnabled,
@Param("deprecatedFilter") boolean deprecatedFilter,
@Param("widgetTypesEmpty") boolean widgetTypesEmpty,
@Param("widgetTypes") List<String> widgetTypes,
Pageable pageable);
}

31
dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java

@ -24,8 +24,6 @@ import org.thingsboard.server.dao.ExportableEntityRepository;
import org.thingsboard.server.dao.model.sql.WidgetTypeDetailsEntity;
import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
import org.thingsboard.server.dao.model.sql.WidgetTypeIdFqnEntity;
import org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity;
import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
import java.util.List;
import java.util.UUID;
@ -37,31 +35,6 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
boolean existsByTenantIdAndId(UUID tenantId, UUID id);
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :systemTenantId " +
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
Page<WidgetTypeInfoEntity> findSystemWidgetTypes(@Param("systemTenantId") UUID systemTenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId IN (:tenantId, :nullTenantId) " +
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
Page<WidgetTypeInfoEntity> findAllTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
@Param("nullTenantId") UUID nullTenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :tenantId " +
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
Page<WidgetTypeInfoEntity> findTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText,
@Param("fullSearch") boolean fullSearch,
Pageable pageable);
@Query("SELECT wtd FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :tenantId " +
"AND LOWER(wtd.name) LIKE LOWER(CONCAT('%', :textSearch, '%'))")
Page<WidgetTypeDetailsEntity> findTenantWidgetTypeDetailsByTenantId(@Param("tenantId") UUID tenantId,
@ -78,10 +51,6 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
"AND wbw.widgetTypeId = wtd.id ORDER BY wbw.widgetTypeOrder")
List<WidgetTypeDetailsEntity> findWidgetTypesDetailsByWidgetsBundleId(@Param("widgetsBundleId") UUID widgetsBundleId);
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd, WidgetsBundleWidgetEntity wbw " +
"WHERE wbw.widgetsBundleId = :widgetsBundleId " +
"AND wbw.widgetTypeId = wtd.id ORDER BY wbw.widgetTypeOrder")
List<WidgetTypeInfoEntity> findWidgetTypesInfosByWidgetsBundleId(@Param("widgetsBundleId") UUID widgetsBundleId);
@Query("SELECT wtd.fqn FROM WidgetTypeDetailsEntity wtd, WidgetsBundleWidgetEntity wbw " +
"WHERE wbw.widgetsBundleId = :widgetsBundleId " +

49
dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java

@ -33,11 +33,33 @@ public interface WidgetsBundleRepository extends JpaRepository<WidgetsBundleEnti
WidgetsBundleEntity findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias);
@Query("SELECT wb FROM WidgetsBundleEntity wb WHERE wb.tenantId = :systemTenantId " +
"AND LOWER(wb.title) LIKE LOWER(CONCAT('%', :searchText, '%'))")
"AND LOWER(wb.title) LIKE LOWER(CONCAT('%', :textSearch, '%'))")
Page<WidgetsBundleEntity> findSystemWidgetsBundles(@Param("systemTenantId") UUID systemTenantId,
@Param("searchText") String searchText,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT * FROM widgets_bundle wb WHERE wb.tenant_id = :systemTenantId " +
"AND (wb.title ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.id in (SELECT wbw.widgets_bundle_id FROM widgets_bundle_widget wbw, widget_type wtd " +
"WHERE wtd.id = wbw.widget_type_id " +
"AND (wtd.name ILIKE CONCAT('%', :textSearch, '%') " +
"OR wtd.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR lower(wtd.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:textSearch), ' '))))",
countQuery = "SELECT count(*) FROM widgets_bundle wb WHERE wb.tenant_id = :systemTenantId " +
"AND (wb.title ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.id in (SELECT wbw.widgets_bundle_id FROM widgets_bundle_widget wbw, widget_type wtd " +
"WHERE wtd.id = wbw.widget_type_id " +
"AND (wtd.name ILIKE CONCAT('%', :textSearch, '%') " +
"OR wtd.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR lower(wtd.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:textSearch), ' '))))"
)
Page<WidgetsBundleEntity> findSystemWidgetsBundlesFullSearch(@Param("systemTenantId") UUID systemTenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT wb FROM WidgetsBundleEntity wb WHERE wb.tenantId = :tenantId " +
"AND LOWER(wb.title) LIKE LOWER(CONCAT('%', :textSearch, '%'))")
Page<WidgetsBundleEntity> findTenantWidgetsBundlesByTenantId(@Param("tenantId") UUID tenantId,
@ -51,6 +73,29 @@ public interface WidgetsBundleRepository extends JpaRepository<WidgetsBundleEnti
@Param("textSearch") String textSearch,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT * FROM widgets_bundle wb WHERE wb.tenant_id IN (:tenantId, :nullTenantId) " +
"AND (wb.title ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.id in (SELECT wbw.widgets_bundle_id FROM widgets_bundle_widget wbw, widget_type wtd " +
"WHERE wtd.id = wbw.widget_type_id " +
"AND (wtd.name ILIKE CONCAT('%', :textSearch, '%') " +
"OR wtd.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR lower(wtd.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:textSearch), ' '))))",
countQuery = "SELECT count(*) FROM widgets_bundle wb WHERE wb.tenant_id IN (:tenantId, :nullTenantId) " +
"AND (wb.title ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR wb.id in (SELECT wbw.widgets_bundle_id FROM widgets_bundle_widget wbw, widget_type wtd " +
"WHERE wtd.id = wbw.widget_type_id " +
"AND (wtd.name ILIKE CONCAT('%', :textSearch, '%') " +
"OR wtd.description ILIKE CONCAT('%', :textSearch, '%') " +
"OR lower(wtd.tags\\:\\:text)\\:\\:text[] && string_to_array(lower(:textSearch), ' '))))"
)
Page<WidgetsBundleEntity> findAllTenantWidgetsBundlesByTenantIdFullSearch(@Param("tenantId") UUID tenantId,
@Param("nullTenantId") UUID nullTenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
WidgetsBundleEntity findFirstByTenantIdAndTitle(UUID tenantId, String title);
@Query("SELECT externalId FROM WidgetsBundleEntity WHERE id = :id")

3
dao/src/main/java/org/thingsboard/server/dao/usage/BasicUsageInfoService.java

@ -67,6 +67,7 @@ public class BasicUsageInfoService implements UsageInfoService {
usageInfo.setMaxAlarms(profileConfiguration.getMaxCreatedAlarms());
usageInfo.setMaxTransportMessages(profileConfiguration.getMaxTransportMessages());
usageInfo.setMaxJsExecutions(profileConfiguration.getMaxJSExecutions());
usageInfo.setMaxTbelExecutions(profileConfiguration.getMaxTbelExecutions());
usageInfo.setMaxEmails(profileConfiguration.getMaxEmails());
usageInfo.setMaxSms(profileConfiguration.getMaxSms());
usageInfo.setSmsEnabled(profileConfiguration.getSmsEnabled());
@ -75,6 +76,7 @@ public class BasicUsageInfoService implements UsageInfoService {
Collection<String> keys = Arrays.asList(
ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey(),
ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.TBEL_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey());
@ -82,6 +84,7 @@ public class BasicUsageInfoService implements UsageInfoService {
List<TsKvEntry> entries = tsService.findLatest(tenantId, apiUsageState.getId(), keys).get();
usageInfo.setTransportMessages(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey()));
usageInfo.setJsExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey()));
usageInfo.setTbelExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TBEL_EXEC_COUNT.getApiCountKey()));
usageInfo.setEmails(getLongValueFromTsEntries(entries, ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey()));
usageInfo.setSms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey()));
usageInfo.setAlarms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey()));

3
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

@ -93,6 +93,7 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
apiUsageState.setTransportState(ApiUsageStateValue.ENABLED);
apiUsageState.setReExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setTbelExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED);
apiUsageState.setSmsExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setEmailExecState(ApiUsageStateValue.ENABLED);
@ -110,6 +111,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
new StringDataEntry(ApiFeature.RE.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.JS.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.TBEL.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.EMAIL.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),

16
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeDao.java

@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
@ -53,11 +54,11 @@ public interface WidgetTypeDao extends Dao<WidgetTypeDetails>, ExportableEntityD
boolean existsByTenantIdAndId(TenantId tenantId, UUID widgetTypeId);
PageData<WidgetTypeInfo> findSystemWidgetTypes(TenantId tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findSystemWidgetTypes(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink);
PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantId(UUID tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
/**
* Find widget types by widgetsBundleId.
@ -77,14 +78,7 @@ public interface WidgetTypeDao extends Dao<WidgetTypeDetails>, ExportableEntityD
*/
List<WidgetTypeDetails> findWidgetTypesDetailsByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId);
/**
* Find widget types infos by widgetsBundleId.
*
* @param tenantId the tenantId
* @param widgetsBundleId the widgets bundle id
* @return the list of widget types infos objects
*/
List<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId);
PageData<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink);
List<String> findWidgetFqnsByWidgetsBundleId(UUID tenantId, UUID widgetsBundleId);

32
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java

@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.WidgetTypeId;
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.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
@ -110,26 +111,28 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
}
@Override
public PageData<WidgetTypeInfo> findSystemWidgetTypesByPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
log.trace("Executing findSystemWidgetTypesByPageLink, fullSearch [{}] pageLink [{}]", fullSearch, pageLink);
public PageData<WidgetTypeInfo> findSystemWidgetTypesByPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
log.trace("Executing findSystemWidgetTypesByPageLink, fullSearch [{}], deprecatedFilter [{}], widgetTypes [{}], pageLink [{}]", fullSearch, deprecatedFilter, widgetTypes, pageLink);
Validator.validatePageLink(pageLink);
return widgetTypeDao.findSystemWidgetTypes(tenantId, fullSearch, pageLink);
return widgetTypeDao.findSystemWidgetTypes(tenantId, fullSearch, deprecatedFilter, widgetTypes, pageLink);
}
@Override
public PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
log.trace("Executing findAllTenantWidgetTypesByTenantIdAndPageLink, tenantId [{}], fullSearch [{}], pageLink [{}]", tenantId, fullSearch, pageLink);
public PageData<WidgetTypeInfo> findAllTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
log.trace("Executing findAllTenantWidgetTypesByTenantIdAndPageLink, tenantId [{}], fullSearch [{}], deprecatedFilter [{}], widgetTypes [{}], pageLink [{}]",
tenantId, fullSearch, deprecatedFilter, widgetTypes, pageLink);
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validatePageLink(pageLink);
return widgetTypeDao.findAllTenantWidgetTypesByTenantId(tenantId.getId(), fullSearch, pageLink);
return widgetTypeDao.findAllTenantWidgetTypesByTenantId(tenantId.getId(), fullSearch, deprecatedFilter, widgetTypes, pageLink);
}
@Override
public PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
log.trace("Executing findTenantWidgetTypesByTenantIdAndPageLink, tenantId [{}], fullSearch [{}], pageLink [{}]", tenantId, fullSearch, pageLink);
public PageData<WidgetTypeInfo> findTenantWidgetTypesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
log.trace("Executing findTenantWidgetTypesByTenantIdAndPageLink, tenantId [{}], fullSearch [{}], deprecatedFilter [{}], widgetTypes [{}], pageLink [{}]",
tenantId, fullSearch, deprecatedFilter, widgetTypes, pageLink);
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validatePageLink(pageLink);
return widgetTypeDao.findTenantWidgetTypesByTenantId(tenantId.getId(), fullSearch, pageLink);
return widgetTypeDao.findTenantWidgetTypesByTenantId(tenantId.getId(), fullSearch, deprecatedFilter, widgetTypes, pageLink);
}
@Override
@ -150,11 +153,14 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
}
@Override
public List<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId) {
log.trace("Executing findWidgetTypesInfosByWidgetsBundleId, tenantId [{}], widgetsBundleId [{}]", tenantId, widgetsBundleId);
public PageData<WidgetTypeInfo> findWidgetTypesInfosByWidgetsBundleId(TenantId tenantId, WidgetsBundleId widgetsBundleId, boolean fullSearch,
DeprecatedFilter deprecatedFilter, List<String> widgetTypes, PageLink pageLink) {
log.trace("Executing findWidgetTypesInfosByWidgetsBundleId, tenantId [{}], widgetsBundleId [{}], fullSearch [{}], deprecatedFilter [{}], widgetTypes [{}], pageLink [{}]",
tenantId, widgetsBundleId, fullSearch, deprecatedFilter, widgetTypes, pageLink);
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validateId(widgetsBundleId, INCORRECT_WIDGETS_BUNDLE_ID + widgetsBundleId);
return widgetTypeDao.findWidgetTypesInfosByWidgetsBundleId(tenantId.getId(), widgetsBundleId.getId());
Validator.validatePageLink(pageLink);
return widgetTypeDao.findWidgetTypesInfosByWidgetsBundleId(tenantId.getId(), widgetsBundleId.getId(), fullSearch, deprecatedFilter, widgetTypes, pageLink);
}
@Override
@ -230,7 +236,7 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
@Override
protected PageData<WidgetTypeInfo> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return widgetTypeDao.findTenantWidgetTypesByTenantId(id.getId(), false, pageLink);
return widgetTypeDao.findTenantWidgetTypesByTenantId(id.getId(), false, DeprecatedFilter.ALL, null, pageLink);
}
@Override

4
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleDao.java

@ -54,7 +54,7 @@ public interface WidgetsBundleDao extends Dao<WidgetsBundle>, ExportableEntityDa
* @param pageLink the page link
* @return the list of widgets bundles objects
*/
PageData<WidgetsBundle> findSystemWidgetsBundles(TenantId tenantId, PageLink pageLink);
PageData<WidgetsBundle> findSystemWidgetsBundles(TenantId tenantId, boolean fullSearch, PageLink pageLink);
/**
* Find tenant widgets bundles by tenantId and page link.
@ -72,7 +72,7 @@ public interface WidgetsBundleDao extends Dao<WidgetsBundle>, ExportableEntityDa
* @param pageLink the page link
* @return the list of widgets bundles objects
*/
PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(UUID tenantId, PageLink pageLink);
PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(UUID tenantId, boolean fullSearch, PageLink pageLink);
}

16
dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java

@ -104,10 +104,10 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
}
@Override
public PageData<WidgetsBundle> findSystemWidgetsBundlesByPageLink(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findSystemWidgetsBundles, pageLink [{}]", pageLink);
public PageData<WidgetsBundle> findSystemWidgetsBundlesByPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
log.trace("Executing findSystemWidgetsBundles, fullSearch [{}], pageLink [{}]", fullSearch, pageLink);
Validator.validatePageLink(pageLink);
return widgetsBundleDao.findSystemWidgetsBundles(tenantId, pageLink);
return widgetsBundleDao.findSystemWidgetsBundles(tenantId, fullSearch, pageLink);
}
@Override
@ -117,7 +117,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
PageLink pageLink = new PageLink(DEFAULT_WIDGETS_BUNDLE_LIMIT);
PageData<WidgetsBundle> pageData;
do {
pageData = findSystemWidgetsBundlesByPageLink(tenantId, pageLink);
pageData = findSystemWidgetsBundlesByPageLink(tenantId, false, pageLink);
widgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -135,11 +135,11 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
}
@Override
public PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantIdAndPageLink(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findAllTenantWidgetsBundlesByTenantIdAndPageLink, tenantId [{}], pageLink [{}]", tenantId, pageLink);
public PageData<WidgetsBundle> findAllTenantWidgetsBundlesByTenantIdAndPageLink(TenantId tenantId, boolean fullSearch, PageLink pageLink) {
log.trace("Executing findAllTenantWidgetsBundlesByTenantIdAndPageLink, tenantId [{}], fullSearch [{}], pageLink [{}]", tenantId, fullSearch, pageLink);
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validatePageLink(pageLink);
return widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId.getId(), pageLink);
return widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId.getId(), fullSearch, pageLink);
}
@Override
@ -150,7 +150,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
PageLink pageLink = new PageLink(DEFAULT_WIDGETS_BUNDLE_LIMIT);
PageData<WidgetsBundle> pageData;
do {
pageData = findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink);
pageData = findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, false, pageLink);
widgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();

2
dao/src/main/resources/sql/schema-entities.sql

@ -489,6 +489,7 @@ CREATE TABLE IF NOT EXISTS widget_type (
image varchar(1000000),
deprecated boolean NOT NULL DEFAULT false,
description varchar(1024),
tags text[],
external_id uuid,
CONSTRAINT uq_widget_type_fqn UNIQUE (tenant_id, fqn),
CONSTRAINT widget_type_external_id_unq_key UNIQUE (tenant_id, external_id)
@ -696,6 +697,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
db_storage varchar(32),
re_exec varchar(32),
js_exec varchar(32),
tbel_exec varchar(32),
email_exec varchar(32),
sms_exec varchar(32),
alarm_exec varchar(32),

6
dao/src/main/resources/sql/schema-views-and-functions.sql

@ -285,3 +285,9 @@ BEGIN
RETURN json_build_object('success', true, 'modified', modified, 'alarm', row_to_json(result))::text;
END
$$;
DROP VIEW IF EXISTS widget_type_info_view CASCADE;
CREATE OR REPLACE VIEW widget_type_info_view AS
SELECT t.*
, COALESCE((t.descriptor::json->>'type')::text, '') as widget_type
FROM widget_type t;

8
dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceTest.java

@ -174,7 +174,7 @@ public class WidgetsBundleServiceTest extends AbstractServiceTest {
PageLink pageLink = new PageLink(19);
PageData<WidgetsBundle> pageData = null;
do {
pageData = widgetsBundleService.findSystemWidgetsBundlesByPageLink(tenantId, pageLink);
pageData = widgetsBundleService.findSystemWidgetsBundlesByPageLink(tenantId, false, pageLink);
loadedWidgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -297,7 +297,7 @@ public class WidgetsBundleServiceTest extends AbstractServiceTest {
PageLink pageLink = new PageLink(17);
PageData<WidgetsBundle> pageData = null;
do {
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink);
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, false, pageLink);
loadedWidgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -314,7 +314,7 @@ public class WidgetsBundleServiceTest extends AbstractServiceTest {
loadedWidgetsBundles.clear();
pageLink = new PageLink(14);
do {
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink);
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, false, pageLink);
loadedWidgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -336,7 +336,7 @@ public class WidgetsBundleServiceTest extends AbstractServiceTest {
loadedWidgetsBundles.clear();
pageLink = new PageLink(18);
do {
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink);
pageData = widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, false, pageLink);
loadedWidgetsBundles.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();

67
dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDaoTest.java

@ -20,10 +20,17 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.id.TenantId;
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.page.SortOrder;
import org.thingsboard.server.common.data.widget.BaseWidgetType;
import org.thingsboard.server.common.data.widget.DeprecatedFilter;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.common.data.widget.WidgetsBundleWidget;
import org.thingsboard.server.dao.AbstractJpaDaoTest;
@ -31,7 +38,10 @@ import org.thingsboard.server.dao.widget.WidgetTypeDao;
import org.thingsboard.server.dao.widget.WidgetsBundleDao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@ -43,7 +53,7 @@ public class JpaWidgetTypeDaoTest extends AbstractJpaDaoTest {
final String BUNDLE_ALIAS = "BUNDLE_ALIAS";
final int WIDGET_TYPE_COUNT = 3;
List<WidgetType> widgetTypeList;
List<WidgetTypeDetails> widgetTypeList;
WidgetsBundle widgetsBundle;
@Autowired
@ -64,17 +74,24 @@ public class JpaWidgetTypeDaoTest extends AbstractJpaDaoTest {
this.widgetsBundle = widgetsBundleDao.save(TenantId.SYS_TENANT_ID, widgetsBundle);
for (int i = 0; i < WIDGET_TYPE_COUNT; i++) {
var widgetType = createAndSaveWidgetType(i);
var widgetType = createAndSaveWidgetType(TenantId.SYS_TENANT_ID, i);
widgetTypeList.add(widgetType);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(this.widgetsBundle.getId(), widgetType.getId(), i));
}
widgetTypeList.sort(Comparator.comparing(BaseWidgetType::getName));
}
WidgetType createAndSaveWidgetType(int number) {
WidgetTypeDetails createAndSaveWidgetType(TenantId tenantId, int number) {
WidgetTypeDetails widgetType = new WidgetTypeDetails();
widgetType.setTenantId(TenantId.SYS_TENANT_ID);
widgetType.setTenantId(tenantId);
widgetType.setName("WIDGET_TYPE_" + number);
widgetType.setDescription("WIDGET_TYPE_DESCRIPTION" + number);
widgetType.setFqn("FQN_" + number);
var descriptor = JacksonUtil.newObjectNode();
descriptor.put("type", number % 2 == 0 ? "latest" : "static");
widgetType.setDescriptor(descriptor);
String[] tags = new String[]{"Tag1_"+number, "Tag2_"+number, "TEST_"+number};
widgetType.setTags(tags);
return widgetTypeDao.save(TenantId.SYS_TENANT_ID, widgetType);
}
@ -92,6 +109,48 @@ public class JpaWidgetTypeDaoTest extends AbstractJpaDaoTest {
assertEquals(WIDGET_TYPE_COUNT, widgetTypes.size());
}
@Test
public void testFindSystemWidgetTypes() {
PageData<WidgetTypeInfo> widgetTypes = widgetTypeDao.findSystemWidgetTypes(TenantId.SYS_TENANT_ID, true, DeprecatedFilter.ALL, Collections.singletonList("static"),
new PageLink(1024, 0, "TYPE_DESCRIPTION", new SortOrder("name")));
assertEquals(1, widgetTypes.getData().size());
assertEquals(new WidgetTypeInfo(widgetTypeList.get(1)), widgetTypes.getData().get(0));
widgetTypes = widgetTypeDao.findSystemWidgetTypes(TenantId.SYS_TENANT_ID, true, DeprecatedFilter.ALL, Collections.emptyList(),
new PageLink(1024, 0, "hfgfd tag2_2 ghg", new SortOrder("name")));
assertEquals(1, widgetTypes.getData().size());
assertEquals(new WidgetTypeInfo(widgetTypeList.get(2)), widgetTypes.getData().get(0));
}
@Test
public void testFindTenantWidgetTypesByTenantId() {
UUID tenantId = Uuids.timeBased();
for (int i = 0; i < WIDGET_TYPE_COUNT; i++) {
var widgetType = createAndSaveWidgetType(new TenantId(tenantId), i);
widgetTypeList.add(widgetType);
}
PageData<WidgetTypeInfo> widgetTypes = widgetTypeDao.findTenantWidgetTypesByTenantId(tenantId, true, DeprecatedFilter.ALL, null,
new PageLink(10, 0, "", new SortOrder("name")));
assertEquals(WIDGET_TYPE_COUNT, widgetTypes.getData().size());
assertEquals(new WidgetTypeInfo(widgetTypeList.get(3)), widgetTypes.getData().get(0));
assertEquals(new WidgetTypeInfo(widgetTypeList.get(4)), widgetTypes.getData().get(1));
assertEquals(new WidgetTypeInfo(widgetTypeList.get(5)), widgetTypes.getData().get(2));
}
@Test
public void testFindByWidgetTypeInfosByBundleId() {
PageData<WidgetTypeInfo> widgetTypes = widgetTypeDao.findWidgetTypesInfosByWidgetsBundleId(TenantId.SYS_TENANT_ID.getId(), widgetsBundle.getUuidId(),true, DeprecatedFilter.ALL, Collections.singletonList("latest"),
new PageLink(1024, 0, "TYPE_DESCRIPTION", new SortOrder("name")));
assertEquals(2, widgetTypes.getData().size());
assertEquals(new WidgetTypeInfo(widgetTypeList.get(0)), widgetTypes.getData().get(0));
assertEquals(new WidgetTypeInfo(widgetTypeList.get(2)), widgetTypes.getData().get(1));
widgetTypes = widgetTypeDao.findWidgetTypesInfosByWidgetsBundleId(TenantId.SYS_TENANT_ID.getId(), widgetsBundle.getUuidId(), true, DeprecatedFilter.ALL, Collections.emptyList(),
new PageLink(1024, 0, "hfgfd TEST_0 ghg", new SortOrder("name")));
assertEquals(1, widgetTypes.getData().size());
assertEquals(new WidgetTypeInfo(widgetTypeList.get(0)), widgetTypes.getData().get(0));
}
@Test
public void testFindByTenantIdAndFqn() {
WidgetType result = widgetTypeList.get(0);

137
dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java

@ -17,18 +17,27 @@ package org.thingsboard.server.dao.sql.widget;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.id.TenantId;
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.page.SortOrder;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.common.data.widget.WidgetsBundleWidget;
import org.thingsboard.server.dao.AbstractJpaDaoTest;
import org.thingsboard.server.dao.widget.WidgetTypeDao;
import org.thingsboard.server.dao.widget.WidgetsBundleDao;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
@ -38,15 +47,27 @@ import static org.junit.Assert.assertEquals;
public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
List<WidgetsBundle> widgetsBundles;
List<WidgetType> widgetTypeList;
@Autowired
private WidgetsBundleDao widgetsBundleDao;
@Autowired
private WidgetTypeDao widgetTypeDao;
@Before
public void setUp() {
widgetTypeList = new ArrayList<>();
}
@After
public void tearDown() {
for (WidgetsBundle widgetsBundle : widgetsBundles) {
widgetsBundleDao.removeById(widgetsBundle.getTenantId(), widgetsBundle.getUuidId());
}
for (WidgetType widgetType : widgetTypeList) {
widgetTypeDao.removeById(TenantId.SYS_TENANT_ID, widgetType.getUuidId());
}
}
@Test
@ -72,14 +93,53 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
assertEquals(30, widgetsBundles.size());
// Get first page
PageLink pageLink = new PageLink(10, 0, "WB");
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, pageLink);
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, false, pageLink);
assertEquals(10, widgetsBundles1.getData().size());
// Get next page
pageLink = pageLink.nextPageLink();
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, pageLink);
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, false, pageLink);
assertEquals(10, widgetsBundles2.getData().size());
}
@Test
public void testFindSystemWidgetsBundlesFullSearch() {
createSystemWidgetBundles(30, "WB_");
widgetsBundles = widgetsBundleDao.find(TenantId.SYS_TENANT_ID).stream().sorted(Comparator.comparing(WidgetsBundle::getTitle)).collect(Collectors.toList());
assertEquals(30, widgetsBundles.size());
var widgetType1 = createAndSaveWidgetType(TenantId.SYS_TENANT_ID,1, "Test widget type 1", "This is the widget type 1", new String[]{"tag1", "Tag2", "TEST_TAG"});
var widgetType2 = createAndSaveWidgetType(TenantId.SYS_TENANT_ID,2, "Test widget type 2", "This is the widget type 2", new String[]{"tag3", "Tag5", "TEST_Tag2"});
var widgetsBundle1 = widgetsBundles.get(10);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle1.getId(), widgetType1.getId(), 0));
var widgetsBundle2 = widgetsBundles.get(15);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle2.getId(), widgetType2.getId(), 0));
var widgetsBundle3 = widgetsBundles.get(28);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle3.getId(), widgetType1.getId(), 0));
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle3.getId(), widgetType2.getId(), 1));
PageLink pageLink = new PageLink(10, 0, "widget type 1", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, true, pageLink);
assertEquals(2, widgetsBundles1.getData().size());
assertEquals(widgetsBundle1, widgetsBundles1.getData().get(0));
assertEquals(widgetsBundle3, widgetsBundles1.getData().get(1));
pageLink = new PageLink(10, 0, "Test widget type 2", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, true, pageLink);
assertEquals(2, widgetsBundles2.getData().size());
assertEquals(widgetsBundle2, widgetsBundles2.getData().get(0));
assertEquals(widgetsBundle3, widgetsBundles2.getData().get(1));
pageLink = new PageLink(10, 0, "ppp Fd v TAG1 tt", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles3 = widgetsBundleDao.findSystemWidgetsBundles(TenantId.SYS_TENANT_ID, true, pageLink);
assertEquals(2, widgetsBundles3.getData().size());
assertEquals(widgetsBundle1, widgetsBundles3.getData().get(0));
assertEquals(widgetsBundle3, widgetsBundles3.getData().get(1));
}
@Test
public void testFindWidgetsBundlesByTenantId() {
UUID tenantId1 = Uuids.timeBased();
@ -120,22 +180,71 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
assertEquals(100, widgetsBundleDao.find(TenantId.SYS_TENANT_ID).size());
PageLink pageLink = new PageLink(30, 0, "WB");
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, pageLink);
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, false, pageLink);
assertEquals(30, widgetsBundles1.getData().size());
pageLink = pageLink.nextPageLink();
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, pageLink);
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, false, pageLink);
assertEquals(30, widgetsBundles2.getData().size());
pageLink = pageLink.nextPageLink();
PageData<WidgetsBundle> widgetsBundles3 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, pageLink);
PageData<WidgetsBundle> widgetsBundles3 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, false, pageLink);
assertEquals(10, widgetsBundles3.getData().size());
pageLink = pageLink.nextPageLink();
PageData<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, pageLink);
PageData<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, false, pageLink);
assertEquals(0, widgetsBundles4.getData().size());
}
@Test
public void testFindAllWidgetsBundlesByTenantIdFullSearch() {
UUID tenantId1 = Uuids.timeBased();
UUID tenantId2 = Uuids.timeBased();
for (int i = 0; i < 10; i++) {
createWidgetBundles(5, tenantId1, "WB1_" + i + "_");
createWidgetBundles(3, tenantId2, "WB2_" + i + "_");
createSystemWidgetBundles(2, "WB_SYS_" + i + "_");
}
widgetsBundles = widgetsBundleDao.find(TenantId.SYS_TENANT_ID).stream().sorted(Comparator.comparing(WidgetsBundle::getTitle)).collect(Collectors.toList());;
assertEquals(100, widgetsBundleDao.find(TenantId.SYS_TENANT_ID).size());
var widgetType1 = createAndSaveWidgetType(new TenantId(tenantId1), 1, "Test widget type 1", "This is the widget type 1", new String[]{"tag1", "Tag2", "TEST_TAG"});
var widgetType2 = createAndSaveWidgetType(new TenantId(tenantId2), 2, "Test widget type 2", "This is the widget type 2", new String[]{"tag3", "Tag5", "TEST_Tag2"});
var widgetsBundle1 = widgetsBundles.stream().filter(widgetsBundle -> widgetsBundle.getTenantId().getId().equals(tenantId1)).collect(Collectors.toList()).get(10);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle1.getId(), widgetType1.getId(), 0));
var widgetsBundle2 = widgetsBundles.stream().filter(widgetsBundle -> widgetsBundle.getTenantId().getId().equals(tenantId2)).collect(Collectors.toList()).get(15);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle2.getId(), widgetType2.getId(), 0));
var widgetsBundle3 = widgetsBundles.stream().filter(widgetsBundle -> widgetsBundle.getTenantId().getId().equals(tenantId2)).collect(Collectors.toList()).get(28);
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle3.getId(), widgetType1.getId(), 0));
widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle3.getId(), widgetType2.getId(), 1));
PageLink pageLink = new PageLink(10, 0, "widget type 1", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, true, pageLink);
assertEquals(1, widgetsBundles1.getData().size());
assertEquals(widgetsBundle1, widgetsBundles1.getData().get(0));
pageLink = new PageLink(10, 0, "Test widget type 2", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, true, pageLink);
assertEquals(0, widgetsBundles2.getData().size());
PageData<WidgetsBundle> widgetsBundles3 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId2, true, pageLink);
assertEquals(2, widgetsBundles3.getData().size());
assertEquals(widgetsBundle2, widgetsBundles3.getData().get(0));
assertEquals(widgetsBundle3, widgetsBundles3.getData().get(1));
pageLink = new PageLink(10, 0, "ttt Tag2 ffff hhhh", new SortOrder("title"));
PageData<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId1, true, pageLink);
assertEquals(1, widgetsBundles4.getData().size());
assertEquals(widgetsBundle1, widgetsBundles4.getData().get(0));
PageData<WidgetsBundle> widgetsBundles5 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId2, true, pageLink);
assertEquals(1, widgetsBundles5.getData().size());
assertEquals(widgetsBundle3, widgetsBundles5.getData().get(0));
}
@Test
public void testSearchTextNotFound() {
UUID tenantId = Uuids.timeBased();
@ -144,7 +253,7 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
widgetsBundles = widgetsBundleDao.find(TenantId.SYS_TENANT_ID);
assertEquals(10, widgetsBundleDao.find(TenantId.SYS_TENANT_ID).size());
PageLink textPageLink = new PageLink(30, 0, "TEXT_NOT_FOUND");
PageData<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId, textPageLink);
PageData<WidgetsBundle> widgetsBundles4 = widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId, false, textPageLink);
assertEquals(0, widgetsBundles4.getData().size());
}
@ -169,4 +278,16 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
widgetsBundleDao.save(TenantId.SYS_TENANT_ID, widgetsBundle);
}
}
WidgetType createAndSaveWidgetType(TenantId tenantId, int number, String name, String description, String[] tags) {
WidgetTypeDetails widgetType = new WidgetTypeDetails();
widgetType.setTenantId(tenantId);
widgetType.setName(name);
widgetType.setDescription(description);
widgetType.setTags(tags);
widgetType.setFqn("FQN_" + number);
var saved = widgetTypeDao.save(TenantId.SYS_TENANT_ID, widgetType);
this.widgetTypeList.add(saved);
return saved;
}
}

2
monitoring/pom.xml

@ -21,7 +21,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>

2
msa/black-box-tests/pom.xml

@ -21,7 +21,7 @@
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/js-executor/package.json

@ -1,7 +1,7 @@
{
"name": "thingsboard-js-executor",
"private": true,
"version": "3.6.0",
"version": "3.6.1",
"description": "ThingsBoard JavaScript Executor Microservice",
"main": "server.ts",
"bin": "server.js",

2
msa/js-executor/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/monitoring/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>

2
msa/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>msa</artifactId>

2
msa/tb-node/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/tb/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.msa</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.msa</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/lwm2m/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.msa</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/mqtt/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.msa</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.msa.transport</groupId>

2
msa/transport/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/transport/snmp/pom.xml

@ -21,7 +21,7 @@
<parent>
<groupId>org.thingsboard.msa</groupId>
<artifactId>transport</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
</parent>
<groupId>org.thingsboard.msa.transport</groupId>

2
msa/vc-executor-docker/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/vc-executor/pom.xml

@ -21,7 +21,7 @@
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

2
msa/web-ui/package.json

@ -1,7 +1,7 @@
{
"name": "thingsboard-web-ui",
"private": true,
"version": "3.6.0",
"version": "3.6.1",
"description": "ThingsBoard Web UI Microservice",
"main": "server.ts",
"bin": "server.js",

2
msa/web-ui/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>msa</artifactId>
</parent>
<groupId>org.thingsboard.msa</groupId>

4
netty-mqtt/pom.xml

@ -19,11 +19,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>netty-mqtt</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Netty MQTT Client</name>

8
pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.thingsboard</groupId>
<artifactId>thingsboard</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Thingsboard</name>
@ -121,6 +121,7 @@
<wire-schema.version>3.4.0</wire-schema.version>
<twilio.version>8.17.0</twilio.version>
<hibernate-validator.version>6.0.20.Final</hibernate-validator.version>
<hypersistence-utils.version>3.5.2</hypersistence-utils.version>
<javax.el.version>3.0.0</javax.el.version>
<javax.validation-api.version>2.0.1.Final</javax.validation-api.version>
<antisamy.version>1.7.2</antisamy.version>
@ -1923,6 +1924,11 @@
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-55</artifactId>
<version>${hypersistence-utils.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>

2
rest-client/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>rest-client</artifactId>

2
rule-engine/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>rule-engine</artifactId>

2
rule-engine/rule-engine-api/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>rule-engine</artifactId>
</parent>
<groupId>org.thingsboard.rule-engine</groupId>

2
rule-engine/rule-engine-components/pom.xml

@ -22,7 +22,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>rule-engine</artifactId>
</parent>
<groupId>org.thingsboard.rule-engine</groupId>

2
tools/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<artifactId>tools</artifactId>

2
transport/coap/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.transport</groupId>

2
transport/http/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.transport</groupId>

2
transport/lwm2m/pom.xml

@ -20,7 +20,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard</groupId>
<version>3.6.0-SNAPSHOT</version>
<version>3.6.1-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.transport</groupId>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save