From da0bd1dc923163d010a3a841c68498c5ed598888 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 24 Apr 2023 13:49:57 +0200 Subject: [PATCH] renamed SingletonSupport to ClusteringMode and refactoring due to comments --- .../main/data/upgrade/3.4.4/schema_update.sql | 6 +++--- .../RuleNodeActorMessageProcessor.java | 20 +++++++++---------- .../AnnotationComponentDiscoveryService.java | 2 +- ...port.java => ComponentClusteringMode.java} | 8 ++++---- .../data/plugin/ComponentDescriptor.java | 12 +++++------ .../server/dao/model/ModelConstants.java | 2 +- .../model/sql/ComponentDescriptorEntity.java | 10 +++++----- .../validator/RuleChainDataValidator.java | 10 +++++----- ...ctComponentDescriptorInsertRepository.java | 2 +- ...qlComponentDescriptorInsertRepository.java | 4 ++-- .../main/resources/sql/schema-entities.sql | 2 +- .../thingsboard/rule/engine/api/RuleNode.java | 4 ++-- .../rule/engine/mqtt/TbMqttNode.java | 4 ++-- .../engine/mqtt/azure/TbAzureIotHubNode.java | 4 ++-- .../rulechain/rule-node-details.component.ts | 4 ++-- .../rulechain/rulechain-page.component.ts | 4 ++-- .../models/component-descriptor.models.ts | 10 +++++----- .../app/shared/models/rule-chain.models.ts | 6 +++--- 18 files changed, 56 insertions(+), 58 deletions(-) rename common/data/src/main/java/org/thingsboard/server/common/data/plugin/{ComponentSingletonSupport.java => ComponentClusteringMode.java} (87%) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index e15a9fb9e9..0dc54a134f 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -617,9 +617,9 @@ ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS singleton_mode bool DEFAULT false UPDATE rule_node SET singleton_mode = true WHERE type IN ('org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode', 'org.thingsboard.rule.engine.mqtt.TbMqttNode'); -ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS singleton varchar(255) DEFAULT 'NOT_SUPPORTED'; +ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS clustering_mode varchar(255) DEFAULT 'ENABLED'; -UPDATE component_descriptor SET singleton = 'SUPPORTED' WHERE name = 'mqtt'; +UPDATE component_descriptor SET clustering_mode = 'USER_PREFERENCE' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.TbMqttNode'; -UPDATE component_descriptor SET singleton = 'ONLY_SINGLETON' WHERE name = 'azure iot hub'; +UPDATE component_descriptor SET clustering_mode = 'SINGLETON' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode'; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java index 3e6853287c..37964a8005 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java @@ -60,7 +60,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor @Getter @Setter private ComponentType type; @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") @Getter @Setter private ComponentScope scope; - @ApiModelProperty(position = 4, value = "", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "SUPPORTED, NOT_SUPPORTEd, ONLY_SINGLETON", example = "SUPPORTED") - @Getter @Setter private ComponentSingletonSupport singleton; + @ApiModelProperty(position = 5, value = "Clustering mode of the RuleNode. This mode represents the ability to start Rule Node in multiple microservices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "USER_PREFERENCE, ENABLED, SINGLETON", example = "ENABLED") + @Getter @Setter private ComponentClusteringMode clusteringMode; @Length(fieldName = "name") - @ApiModelProperty(position = 5, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "Custom Rule Node") + @ApiModelProperty(position = 6, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "Custom Rule Node") @Getter @Setter private String name; - @ApiModelProperty(position = 6, value = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") + @ApiModelProperty(position = 7, value = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") @Getter @Setter private String clazz; - @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @ApiModelProperty(position = 8, value = "Complex JSON object that represents the Rule Node configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private transient JsonNode configurationDescriptor; @Length(fieldName = "actions") - @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @ApiModelProperty(position = 9, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; public ComponentDescriptor() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 7b1df3c4a9..bcbed91d2a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -403,7 +403,7 @@ public class ModelConstants { public static final String COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME = "component_descriptor"; public static final String COMPONENT_DESCRIPTOR_TYPE_PROPERTY = "type"; public static final String COMPONENT_DESCRIPTOR_SCOPE_PROPERTY = "scope"; - public static final String COMPONENT_DESCRIPTOR_SINGLETON_PROPERTY = "singleton"; + public static final String COMPONENT_DESCRIPTOR_CLUSTERING_MODE_PROPERTY = "clustering_mode"; public static final String COMPONENT_DESCRIPTOR_NAME_PROPERTY = "name"; public static final String COMPONENT_DESCRIPTOR_CLASS_PROPERTY = "clazz"; public static final String COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY = "configuration_descriptor"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java index 47c34e0d58..f22ccffed9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java @@ -23,7 +23,7 @@ import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.ComponentDescriptorId; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentScope; -import org.thingsboard.server.common.data.plugin.ComponentSingletonSupport; +import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; @@ -52,8 +52,8 @@ public class ComponentDescriptorEntity extends BaseSqlEntity { } ConstraintValidator.validateFields(nodeConfig, errorPrefix); - ComponentSingletonSupport nodeConfigType = null; + ComponentClusteringMode nodeConfigType = null; try { nodeConfigType = ReflectionUtils.getAnnotationProperty(ruleNode.getType(), - "org.thingsboard.rule.engine.api.RuleNode", "singleton"); + "org.thingsboard.rule.engine.api.RuleNode", "clusteringMode"); } catch (Exception e) { log.warn("Failed to validate singleton mode: {}", ExceptionUtils.getRootCauseMessage(e)); return; } - if (ComponentSingletonSupport.NOT_SUPPORTED.equals(nodeConfigType) && ruleNode.isSingletonMode()) { + if (ComponentClusteringMode.ENABLED.equals(nodeConfigType) && ruleNode.isSingletonMode()) { throw new DataValidationException(String.format("Singleton mode not supported for [%s].", ruleNode.getType())); } - if (ComponentSingletonSupport.ONLY_SINGLETON.equals(nodeConfigType) && !ruleNode.isSingletonMode()) { + if (ComponentClusteringMode.SINGLETON.equals(nodeConfigType) && !ruleNode.isSingletonMode()) { throw new DataValidationException(String.format("Supported only singleton mode for [%s].", ruleNode.getType())); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java index 4aba74d2cb..943697149c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java @@ -77,7 +77,7 @@ public abstract class AbstractComponentDescriptorInsertRepository implements Com .setParameter("scope", entity.getScope().name()) .setParameter("search_text", entity.getSearchText()) .setParameter("type", entity.getType().name()) - .setParameter("singleton", entity.getSingleton().name()); + .setParameter("clustering_mode", entity.getClusteringMode().name()); } private ComponentDescriptorEntity processSaveOrUpdate(ComponentDescriptorEntity entity, String query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java index 0db38f2c71..08606f6737 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java @@ -44,10 +44,10 @@ public class SqlComponentDescriptorInsertRepository extends AbstractComponentDes } private static String getInsertOrUpdateStatement(String conflictKeyStatement, String updateKeyStatement) { - return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type, singleton) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :name, :scope, :search_text, :type, :singleton) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; + return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type, clustering_mode) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :name, :scope, :search_text, :type, :clustering_mode) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; } private static String getUpdateStatement(String id) { - return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, name = :name, scope = :scope, search_text = :search_text, type = :type, singleton = :singleton"; + return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, name = :name, scope = :scope, search_text = :search_text, type = :type, clustering_mode = :clustering_mode"; } } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 2fdc8e4ce0..c22feb0695 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -126,7 +126,7 @@ CREATE TABLE IF NOT EXISTS component_descriptor ( scope varchar(255), search_text varchar(255), type varchar(255), - singleton varchar(255) + clustering_mode varchar(255) ); CREATE TABLE IF NOT EXISTS customer ( diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java index 9fb8bb66c0..3f7c22576f 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java @@ -16,7 +16,7 @@ package org.thingsboard.rule.engine.api; import org.thingsboard.server.common.data.plugin.ComponentScope; -import org.thingsboard.server.common.data.plugin.ComponentSingletonSupport; +import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; @@ -39,7 +39,7 @@ public @interface RuleNode { Class configClazz(); - ComponentSingletonSupport singleton() default ComponentSingletonSupport.NOT_SUPPORTED; + ComponentClusteringMode clusteringMode() default ComponentClusteringMode.ENABLED; boolean inEnabled() default true; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java index 95ba04d687..86b03cf62e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java @@ -33,7 +33,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.credentials.BasicCredentials; import org.thingsboard.rule.engine.credentials.ClientCredentials; import org.thingsboard.rule.engine.credentials.CredentialsType; -import org.thingsboard.server.common.data.plugin.ComponentSingletonSupport; +import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -48,7 +48,7 @@ import java.util.concurrent.TimeoutException; type = ComponentType.EXTERNAL, name = "mqtt", configClazz = TbMqttNodeConfiguration.class, - singleton = ComponentSingletonSupport.SUPPORTED, + clusteringMode = ComponentClusteringMode.USER_PREFERENCE, nodeDescription = "Publish messages to the MQTT broker", nodeDetails = "Will publish message payload to the MQTT broker with QoS AT_LEAST_ONCE.", uiResources = {"static/rulenode/rulenode-core-config.js"}, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java index 0b3d8f36ad..5720f66038 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNode.java @@ -29,7 +29,7 @@ import org.thingsboard.rule.engine.credentials.ClientCredentials; import org.thingsboard.rule.engine.credentials.CredentialsType; import org.thingsboard.rule.engine.mqtt.TbMqttNode; import org.thingsboard.rule.engine.mqtt.TbMqttNodeConfiguration; -import org.thingsboard.server.common.data.plugin.ComponentSingletonSupport; +import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentType; import javax.net.ssl.SSLException; @@ -39,7 +39,7 @@ import javax.net.ssl.SSLException; type = ComponentType.EXTERNAL, name = "azure iot hub", configClazz = TbAzureIotHubNodeConfiguration.class, - singleton = ComponentSingletonSupport.ONLY_SINGLETON, + clusteringMode = ComponentClusteringMode.SINGLETON, nodeDescription = "Publish messages to the Azure IoT Hub", nodeDetails = "Will publish message payload to the Azure IoT Hub with QoS AT_LEAST_ONCE.", uiResources = {"static/rulenode/rulenode-core-config.js"}, diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts index 320ece312b..dad1e715ec 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts @@ -26,7 +26,7 @@ import { RuleChainService } from '@core/http/rule-chain.service'; import { RuleNodeConfigComponent } from './rule-node-config.component'; import { Router } from '@angular/router'; import { RuleChainType } from '@app/shared/models/rule-chain.models'; -import { ComponentSingletonSupport } from '@shared/models/component-descriptor.models'; +import { ComponentClusteringMode } from '@shared/models/component-descriptor.models'; @Component({ selector: 'tb-rule-node', @@ -134,6 +134,6 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } isSingletonEditAllowed() { - return this.ruleNode.component.singleton === ComponentSingletonSupport.SUPPORTED; + return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE; } } diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 9e68306ac4..7fff22a12a 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -89,7 +89,7 @@ import { DebugEventType, EventType } from '@shared/models/event.models'; import { MatMiniFabButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { VersionControlComponent } from '@home/components/vc/version-control.component'; -import { ComponentSingletonSupport } from '@shared/models/component-descriptor.models'; +import { ComponentClusteringMode } from '@shared/models/component-descriptor.models'; import Timeout = NodeJS.Timeout; @Component({ @@ -470,7 +470,7 @@ export class RuleChainPageComponent extends PageComponent component: ruleNodeComponent, name: '', nodeClass: desc.nodeClass, - singletonMode: ruleNodeComponent.singleton !== ComponentSingletonSupport.NOT_SUPPORTED, + singletonMode: ruleNodeComponent.clusteringMode !== ComponentClusteringMode.ENABLED, icon, iconUrl, x: 30, diff --git a/ui-ngx/src/app/shared/models/component-descriptor.models.ts b/ui-ngx/src/app/shared/models/component-descriptor.models.ts index d8e4aba2aa..3ce15d15aa 100644 --- a/ui-ngx/src/app/shared/models/component-descriptor.models.ts +++ b/ui-ngx/src/app/shared/models/component-descriptor.models.ts @@ -30,16 +30,16 @@ export enum ComponentScope { TENANT = 'TENANT' } -export enum ComponentSingletonSupport { - SUPPORTED = 'SUPPORTED', - NOT_SUPPORTED = 'NOT_SUPPORTED', - ONLY_SINGLETON = 'ONLY_SINGLETON' +export enum ComponentClusteringMode { + USER_PREFERENCE = 'USER_PREFERENCE', + ENABLED = 'ENABLED', + SINGLETON = 'SINGLETON' } export interface ComponentDescriptor { type: ComponentType | RuleNodeType; scope?: ComponentScope; - singleton: ComponentSingletonSupport; + clusteringMode: ComponentClusteringMode; name: string; clazz: string; configurationDescriptor?: any; diff --git a/ui-ngx/src/app/shared/models/rule-chain.models.ts b/ui-ngx/src/app/shared/models/rule-chain.models.ts index 57a58ba110..fbf6f57268 100644 --- a/ui-ngx/src/app/shared/models/rule-chain.models.ts +++ b/ui-ngx/src/app/shared/models/rule-chain.models.ts @@ -19,7 +19,7 @@ import { TenantId } from '@shared/models/id/tenant-id'; import { RuleChainId } from '@shared/models/id/rule-chain-id'; import { RuleNodeId } from '@shared/models/id/rule-node-id'; import { RuleNode, RuleNodeComponentDescriptor, RuleNodeType } from '@shared/models/rule-node.models'; -import { ComponentSingletonSupport, ComponentType } from '@shared/models/component-descriptor.models'; +import { ComponentClusteringMode, ComponentType } from '@shared/models/component-descriptor.models'; export interface RuleChain extends BaseData, ExportableEntity { tenantId: TenantId; @@ -64,7 +64,7 @@ export const ruleNodeTypeComponentTypes: ComponentType[] = export const unknownNodeComponent: RuleNodeComponentDescriptor = { type: RuleNodeType.UNKNOWN, name: 'unknown', - singleton: ComponentSingletonSupport.NOT_SUPPORTED, + clusteringMode: ComponentClusteringMode.ENABLED, clazz: 'tb.internal.Unknown', configurationDescriptor: { nodeDefinition: { @@ -81,7 +81,7 @@ export const unknownNodeComponent: RuleNodeComponentDescriptor = { export const inputNodeComponent: RuleNodeComponentDescriptor = { type: RuleNodeType.INPUT, - singleton: ComponentSingletonSupport.NOT_SUPPORTED, + clusteringMode: ComponentClusteringMode.ENABLED, name: 'Input', clazz: 'tb.internal.Input' };