Provide support for Notification to Edge
This commit is contained in:
		
							parent
							
								
									18178b5243
								
							
						
					
					
						commit
						5191143c3f
					
				@ -175,71 +175,31 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
 | 
			
		||||
                    }
 | 
			
		||||
                    EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType());
 | 
			
		||||
                    switch (type) {
 | 
			
		||||
                        case EDGE:
 | 
			
		||||
                            edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ASSET:
 | 
			
		||||
                            assetProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ASSET_PROFILE:
 | 
			
		||||
                            assetProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case DEVICE:
 | 
			
		||||
                            deviceProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case DEVICE_PROFILE:
 | 
			
		||||
                            deviceProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ENTITY_VIEW:
 | 
			
		||||
                            entityViewProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case DASHBOARD:
 | 
			
		||||
                            dashboardProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case RULE_CHAIN:
 | 
			
		||||
                            ruleChainProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case USER:
 | 
			
		||||
                            userProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case CUSTOMER:
 | 
			
		||||
                            customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case OTA_PACKAGE:
 | 
			
		||||
                            otaPackageProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case WIDGETS_BUNDLE:
 | 
			
		||||
                            widgetBundleProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case WIDGET_TYPE:
 | 
			
		||||
                            widgetTypeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case QUEUE:
 | 
			
		||||
                            queueProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ALARM:
 | 
			
		||||
                            alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case ALARM_COMMENT:
 | 
			
		||||
                            alarmProcessor.processAlarmCommentNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case RELATION:
 | 
			
		||||
                            relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case TENANT:
 | 
			
		||||
                            tenantEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case TENANT_PROFILE:
 | 
			
		||||
                            tenantProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case TB_RESOURCE:
 | 
			
		||||
                            resourceEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case OAUTH2:
 | 
			
		||||
                            oAuth2EdgeProcessor.processOAuth2Notification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            log.warn("[{}] Edge event type [{}] is not designed to be pushed to edge", tenantId, type);
 | 
			
		||||
                        case EDGE -> edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case ASSET -> assetProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case ASSET_PROFILE -> assetProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case DEVICE -> deviceProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case DEVICE_PROFILE -> deviceProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case ENTITY_VIEW -> entityViewProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case DASHBOARD -> dashboardProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case RULE_CHAIN -> ruleChainProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case USER -> userProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case CUSTOMER -> customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case OTA_PACKAGE -> otaPackageProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case WIDGETS_BUNDLE -> widgetBundleProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case WIDGET_TYPE -> widgetTypeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case QUEUE -> queueProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case ALARM -> alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case ALARM_COMMENT -> alarmProcessor.processAlarmCommentNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case RELATION -> relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case TENANT -> tenantEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case TENANT_PROFILE -> tenantProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case NOTIFICATION_RULE -> System.out.println();
 | 
			
		||||
                        case NOTIFICATION_TARGET -> System.out.println();
 | 
			
		||||
                        case NOTIFICATION_TEMPLATE -> System.out.println();
 | 
			
		||||
                        case TB_RESOURCE -> resourceEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        case OAUTH2 -> oAuth2EdgeProcessor.processOAuth2Notification(tenantId, edgeNotificationMsg);
 | 
			
		||||
                        default -> log.warn("[{}] Edge event type [{}] is not designed to be pushed to edge", tenantId, type);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    callBackFailure(tenantId, edgeNotificationMsg, callback, e);
 | 
			
		||||
@ -255,4 +215,5 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
 | 
			
		||||
        log.error("[{}] Can't push to edge updates, edgeNotificationMsg [{}]", tenantId, edgeNotificationMsg, throwable);
 | 
			
		||||
        callback.onFailure(throwable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,9 @@ import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeEventService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeService;
 | 
			
		||||
import org.thingsboard.server.dao.entityview.EntityViewService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationRuleService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTemplateService;
 | 
			
		||||
import org.thingsboard.server.dao.oauth2.OAuth2Service;
 | 
			
		||||
import org.thingsboard.server.dao.ota.OtaPackageService;
 | 
			
		||||
import org.thingsboard.server.dao.queue.QueueService;
 | 
			
		||||
@ -62,6 +65,7 @@ import org.thingsboard.server.service.edge.rpc.processor.device.profile.DevicePr
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.edge.EdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.ota.OtaPackageEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.queue.QueueEdgeProcessor;
 | 
			
		||||
@ -153,6 +157,15 @@ public class EdgeContextComponent {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ResourceService resourceService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private NotificationRuleService notificationRuleService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private NotificationTargetService notificationTargetService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private NotificationTemplateService notificationTemplateService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private OAuth2Service oAuth2Service;
 | 
			
		||||
 | 
			
		||||
@ -225,6 +238,9 @@ public class EdgeContextComponent {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ResourceEdgeProcessor resourceEdgeProcessor;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private NotificationEdgeProcessor notificationEdgeProcessor;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private OAuth2EdgeProcessor oAuth2EdgeProcessor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -683,6 +683,12 @@ public final class EdgeGrpcSession implements Closeable {
 | 
			
		||||
                return ctx.getTenantEdgeProcessor().convertTenantEventToDownlink(edgeEvent, this.edgeVersion);
 | 
			
		||||
            case TENANT_PROFILE:
 | 
			
		||||
                return ctx.getTenantProfileEdgeProcessor().convertTenantProfileEventToDownlink(edgeEvent, this.edgeVersion);
 | 
			
		||||
            case NOTIFICATION_RULE:
 | 
			
		||||
                return ctx.getNotificationEdgeProcessor().convertNotificationRuleToDownlink(edgeEvent);
 | 
			
		||||
            case NOTIFICATION_TARGET:
 | 
			
		||||
                return ctx.getNotificationEdgeProcessor().convertNotificationTargetToDownlink(edgeEvent);
 | 
			
		||||
            case NOTIFICATION_TEMPLATE:
 | 
			
		||||
                return ctx.getNotificationEdgeProcessor().convertNotificationTemplateToDownlink(edgeEvent);
 | 
			
		||||
            case OAUTH2:
 | 
			
		||||
                return ctx.getOAuth2EdgeProcessor().convertOAuth2EventToDownlink(edgeEvent);
 | 
			
		||||
            default:
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,9 @@ import org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetc
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.DevicesEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.EntityViewsEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.NotificationRuleEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.NotificationTargetEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.NotificationTemplateEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.OAuth2EdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.OtaPackagesEdgeEventFetcher;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.fetch.QueuesEdgeEventFetcher;
 | 
			
		||||
@ -74,6 +77,9 @@ public class EdgeSyncCursor {
 | 
			
		||||
        fetchers.add(new AssetsEdgeEventFetcher(ctx.getAssetService()));
 | 
			
		||||
        fetchers.add(new EntityViewsEdgeEventFetcher(ctx.getEntityViewService()));
 | 
			
		||||
        if (fullSync) {
 | 
			
		||||
            fetchers.add(new NotificationTemplateEdgeEventFetcher(ctx.getNotificationTemplateService()));
 | 
			
		||||
            fetchers.add(new NotificationTargetEdgeEventFetcher(ctx.getNotificationTargetService()));
 | 
			
		||||
            fetchers.add(new NotificationRuleEdgeEventFetcher(ctx.getNotificationRuleService()));
 | 
			
		||||
            fetchers.add(new SystemWidgetTypesEdgeEventFetcher(ctx.getWidgetTypeService()));
 | 
			
		||||
            fetchers.add(new TenantWidgetTypesEdgeEventFetcher(ctx.getWidgetTypeService()));
 | 
			
		||||
            fetchers.add(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService()));
 | 
			
		||||
@ -100,4 +106,5 @@ public class EdgeSyncCursor {
 | 
			
		||||
    public int getCurrentIdx() {
 | 
			
		||||
        return currentIdx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,4 +28,5 @@ public abstract class BaseDashboardMsgConstructor implements DashboardMsgConstru
 | 
			
		||||
                .setIdMSB(dashboardId.getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(dashboardId.getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,4 +26,5 @@ public interface DashboardMsgConstructor extends MsgConstructor {
 | 
			
		||||
    DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard);
 | 
			
		||||
 | 
			
		||||
    DashboardUpdateMsg constructDashboardDeleteMsg(DashboardId dashboardId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,4 +32,5 @@ public class DashboardMsgConstructorV2 extends BaseDashboardMsgConstructor {
 | 
			
		||||
                .setIdMSB(dashboard.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(dashboard.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -43,4 +43,5 @@ public interface DeviceMsgConstructor extends MsgConstructor {
 | 
			
		||||
    DeviceProfileUpdateMsg constructDeviceProfileDeleteMsg(DeviceProfileId deviceProfileId);
 | 
			
		||||
 | 
			
		||||
    DeviceRpcCallMsg constructDeviceRpcCallMsg(UUID deviceId, JsonNode body);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -48,4 +48,5 @@ public class DeviceMsgConstructorV2 extends BaseDeviceMsgConstructor {
 | 
			
		||||
                .setIdMSB(deviceProfile.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(deviceProfile.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -43,4 +43,5 @@ public class EdgeMsgConstructor {
 | 
			
		||||
        }
 | 
			
		||||
        return builder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,4 +28,5 @@ public abstract class BaseEntityViewMsgConstructor implements EntityViewMsgConst
 | 
			
		||||
                .setIdMSB(entityViewId.getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(entityViewId.getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,4 +26,5 @@ public interface EntityViewMsgConstructor extends MsgConstructor {
 | 
			
		||||
    EntityViewUpdateMsg constructEntityViewUpdatedMsg(UpdateMsgType msgType, EntityView entityView);
 | 
			
		||||
 | 
			
		||||
    EntityViewUpdateMsg constructEntityViewDeleteMsg(EntityViewId entityViewId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -51,13 +51,11 @@ public class EntityViewMsgConstructorV1 extends BaseEntityViewMsgConstructor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private EdgeEntityType checkEntityType(EntityType entityType) {
 | 
			
		||||
        switch (entityType) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
                return EdgeEntityType.DEVICE;
 | 
			
		||||
            case ASSET:
 | 
			
		||||
                return EdgeEntityType.ASSET;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new RuntimeException("Unsupported entity type [" + entityType + "]");
 | 
			
		||||
        }
 | 
			
		||||
        return switch (entityType) {
 | 
			
		||||
            case DEVICE -> EdgeEntityType.DEVICE;
 | 
			
		||||
            case ASSET -> EdgeEntityType.ASSET;
 | 
			
		||||
            default -> throw new RuntimeException("Unsupported entity type [" + entityType + "]");
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,4 +32,5 @@ public class EntityViewMsgConstructorV2 extends BaseEntityViewMsgConstructor {
 | 
			
		||||
                .setIdMSB(entityView.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(entityView.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,43 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.constructor.notification;
 | 
			
		||||
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationRuleId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTemplateId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
 | 
			
		||||
 | 
			
		||||
public interface NotificationMsgConstructor {
 | 
			
		||||
 | 
			
		||||
    NotificationRuleUpdateMsg constructNotificationRuleUpdateMsg(UpdateMsgType msgType, NotificationRule notificationRule);
 | 
			
		||||
 | 
			
		||||
    NotificationRuleUpdateMsg constructNotificationRuleDeleteMsg(NotificationRuleId notificationRuleId);
 | 
			
		||||
 | 
			
		||||
    NotificationTargetUpdateMsg constructNotificationTargetUpdateMsg(UpdateMsgType msgType, NotificationTarget notificationTarget);
 | 
			
		||||
 | 
			
		||||
    NotificationTargetUpdateMsg constructNotificationTargetDeleteMsg(NotificationTargetId notificationTargetId);
 | 
			
		||||
 | 
			
		||||
    NotificationTemplateUpdateMsg constructNotificationTemplateUpdateMsg(UpdateMsgType msgType, NotificationTemplate notificationTemplate);
 | 
			
		||||
 | 
			
		||||
    NotificationTemplateUpdateMsg constructNotificationTemplateDeleteMsg(NotificationTemplateId notificationTemplateId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,81 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.constructor.notification;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationRuleId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTemplateId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
public class NotificationMsgConstructorImpl implements NotificationMsgConstructor {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationRuleUpdateMsg constructNotificationRuleUpdateMsg(UpdateMsgType msgType, NotificationRule notificationRule) {
 | 
			
		||||
        return NotificationRuleUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationRule))
 | 
			
		||||
                .setIdMSB(notificationRule.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationRule.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationRuleUpdateMsg constructNotificationRuleDeleteMsg(NotificationRuleId notificationRuleId) {
 | 
			
		||||
        return NotificationRuleUpdateMsg.newBuilder()
 | 
			
		||||
                .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
 | 
			
		||||
                .setIdMSB(notificationRuleId.getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationRuleId.getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTargetUpdateMsg constructNotificationTargetUpdateMsg(UpdateMsgType msgType, NotificationTarget notificationTarget) {
 | 
			
		||||
        return NotificationTargetUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationTarget))
 | 
			
		||||
                .setIdMSB(notificationTarget.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationTarget.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTargetUpdateMsg constructNotificationTargetDeleteMsg(NotificationTargetId notificationTargetId) {
 | 
			
		||||
        return NotificationTargetUpdateMsg.newBuilder()
 | 
			
		||||
                .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
 | 
			
		||||
                .setIdMSB(notificationTargetId.getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationTargetId.getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTemplateUpdateMsg constructNotificationTemplateUpdateMsg(UpdateMsgType msgType, NotificationTemplate notificationTemplate) {
 | 
			
		||||
        return NotificationTemplateUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationTemplate))
 | 
			
		||||
                .setIdMSB(notificationTemplate.getId().getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationTemplate.getId().getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTemplateUpdateMsg constructNotificationTemplateDeleteMsg(NotificationTemplateId notificationTemplateId) {
 | 
			
		||||
        return NotificationTemplateUpdateMsg.newBuilder()
 | 
			
		||||
                .setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
 | 
			
		||||
                .setIdMSB(notificationTemplateId.getId().getMostSignificantBits())
 | 
			
		||||
                .setIdLSB(notificationTemplateId.getId().getLeastSignificantBits()).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -62,4 +62,5 @@ public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher {
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class AssetProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher<
 | 
			
		||||
    private final AssetProfileService assetProfileService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<AssetProfile> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<AssetProfile> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return assetProfileService.findAssetProfiles(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class AssetProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher<
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET_PROFILE,
 | 
			
		||||
                EdgeEventActionType.ADDED, assetProfile.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Asset>
 | 
			
		||||
    private final AssetService assetService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<Asset> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<Asset> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,17 +36,18 @@ public abstract class BasePageableEdgeEventFetcher<T> implements EdgeEventFetche
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<EdgeEvent> fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId());
 | 
			
		||||
        PageData<T> pageData = fetchPageData(tenantId, edge, pageLink);
 | 
			
		||||
        PageData<T> entities = fetchEntities(tenantId, edge, pageLink);
 | 
			
		||||
        List<EdgeEvent> result = new ArrayList<>();
 | 
			
		||||
        if (!pageData.getData().isEmpty()) {
 | 
			
		||||
            for (T entity : pageData.getData()) {
 | 
			
		||||
        if (!entities.getData().isEmpty()) {
 | 
			
		||||
            for (T entity : entities.getData()) {
 | 
			
		||||
                result.add(constructEdgeEvent(tenantId, edge, entity));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext());
 | 
			
		||||
        return new PageData<>(result, entities.getTotalPages(), entities.getTotalElements(), entities.hasNext());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract PageData<T> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink);
 | 
			
		||||
    abstract PageData<T> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    abstract EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, T entity);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFet
 | 
			
		||||
    protected final UserService userService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<User> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<User> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return findUsers(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -46,4 +46,5 @@ public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract PageData<User> findUsers(TenantId tenantId, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,11 +25,8 @@ import org.thingsboard.server.common.data.edge.EdgeEventType;
 | 
			
		||||
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.WidgetTypeDetails;
 | 
			
		||||
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.widget.WidgetsBundle;
 | 
			
		||||
import org.thingsboard.server.dao.widget.WidgetTypeService;
 | 
			
		||||
import org.thingsboard.server.dao.widget.WidgetsBundleService;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@ -38,7 +35,7 @@ public abstract class BaseWidgetTypesEdgeEventFetcher extends BasePageableEdgeEv
 | 
			
		||||
    protected final WidgetTypeService widgetTypeService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<WidgetTypeInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<WidgetTypeInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return findWidgetTypes(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -49,4 +46,5 @@ public abstract class BaseWidgetTypesEdgeEventFetcher extends BasePageableEdgeEv
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract PageData<WidgetTypeInfo> findWidgetTypes(TenantId tenantId, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdg
 | 
			
		||||
    protected final WidgetsBundleService widgetsBundleService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<WidgetsBundle> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<WidgetsBundle> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return findWidgetsBundles(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -46,4 +46,5 @@ public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdg
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract PageData<WidgetsBundle> findWidgetsBundles(TenantId tenantId, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -49,4 +49,5 @@ public class CustomerEdgeEventFetcher implements EdgeEventFetcher {
 | 
			
		||||
        // returns PageData object to be in sync with other fetchers
 | 
			
		||||
        return new PageData<>(result, 1, result.size(), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,4 +35,5 @@ public class CustomerUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher {
 | 
			
		||||
    protected PageData<User> findUsers(TenantId tenantId, PageLink pageLink) {
 | 
			
		||||
        return userService.findCustomerUsers(tenantId, customerId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Das
 | 
			
		||||
    private final DashboardService dashboardService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<DashboardInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<DashboardInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Das
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD,
 | 
			
		||||
                EdgeEventActionType.ADDED, dashboardInfo.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -59,4 +59,5 @@ public class DefaultProfilesEdgeEventFetcher implements EdgeEventFetcher {
 | 
			
		||||
 | 
			
		||||
        return new PageData<>(result, 1, result.size(), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -35,7 +35,7 @@ public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher
 | 
			
		||||
    private final DeviceProfileService deviceProfileService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<DeviceProfile> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<DeviceProfile> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return deviceProfileService.findDeviceProfiles(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE,
 | 
			
		||||
                EdgeEventActionType.ADDED, deviceProfile.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class DevicesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Device
 | 
			
		||||
    private final DeviceService deviceService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<Device> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<Device> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class DevicesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Device
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE,
 | 
			
		||||
                EdgeEventActionType.ADDED, device.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,4 +26,5 @@ public interface EdgeEventFetcher {
 | 
			
		||||
    PageLink getPageLink(int pageSize);
 | 
			
		||||
 | 
			
		||||
    PageData<EdgeEvent> fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) throws Exception;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class EntityViewsEdgeEventFetcher extends BasePageableEdgeEventFetcher<En
 | 
			
		||||
    private final EntityViewService entityViewService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<EntityView> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<EntityView> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class EntityViewsEdgeEventFetcher extends BasePageableEdgeEventFetcher<En
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW,
 | 
			
		||||
                EdgeEventActionType.ADDED, entityView.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -73,4 +73,5 @@ public class GeneralEdgeEventFetcher implements EdgeEventFetcher {
 | 
			
		||||
        }
 | 
			
		||||
        return new PageData<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,48 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.fetch;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationRuleService;
 | 
			
		||||
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class NotificationRuleEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationRule>{
 | 
			
		||||
 | 
			
		||||
    private NotificationRuleService notificationRuleService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<NotificationRule> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return notificationRuleService.findNotificationRulesByTenantId(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationRule notificationRule) {
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_RULE,
 | 
			
		||||
                EdgeEventActionType.ADDED, notificationRule.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,48 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.fetch;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
 | 
			
		||||
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class NotificationTargetEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationTarget> {
 | 
			
		||||
 | 
			
		||||
    private NotificationTargetService notificationTargetService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<NotificationTarget> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return notificationTargetService.findNotificationTargetsByTenantId(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationTarget notificationTarget) {
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_TARGET,
 | 
			
		||||
                EdgeEventActionType.ADDED, notificationTarget.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,51 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.fetch;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.Edge;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventType;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTemplateService;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class NotificationTemplateEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationTemplate> {
 | 
			
		||||
 | 
			
		||||
    private NotificationTemplateService notificationTemplateService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<NotificationTemplate> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(NotificationType.values()), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationTemplate notificationTemplate) {
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_TEMPLATE,
 | 
			
		||||
                EdgeEventActionType.ADDED, notificationTemplate.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -35,7 +35,7 @@ public class OtaPackagesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Ot
 | 
			
		||||
    private final OtaPackageService otaPackageService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<OtaPackageInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<OtaPackageInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return otaPackageService.findTenantOtaPackagesByTenantId(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class OtaPackagesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Ot
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.OTA_PACKAGE,
 | 
			
		||||
                EdgeEventActionType.ADDED, otaPackageInfo.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class QueuesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Queue>
 | 
			
		||||
    private final QueueService queueService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<Queue> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<Queue> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return queueService.findQueuesByTenantId(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class QueuesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Queue>
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.QUEUE,
 | 
			
		||||
                EdgeEventActionType.ADDED, queue.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Rul
 | 
			
		||||
    private final RuleChainService ruleChainService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<RuleChain> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<RuleChain> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -54,4 +54,5 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Rul
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN,
 | 
			
		||||
                EdgeEventActionType.ADDED, ruleChain.getId(), isRootBody);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ public class TenantEdgeEventFetcher extends BasePageableEdgeEventFetcher<Tenant>
 | 
			
		||||
    private final TenantService tenantService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<Tenant> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<Tenant> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        Tenant tenant = tenantService.findTenantById(tenantId);
 | 
			
		||||
        // returns PageData object to be in sync with other fetchers
 | 
			
		||||
        return new PageData<>(List.of(tenant), 1, 1, false);
 | 
			
		||||
@ -48,4 +48,5 @@ public class TenantEdgeEventFetcher extends BasePageableEdgeEventFetcher<Tenant>
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.TENANT,
 | 
			
		||||
                EdgeEventActionType.UPDATED, entity.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ public class TenantResourcesEdgeEventFetcher extends BasePageableEdgeEventFetche
 | 
			
		||||
    private final ResourceService resourceService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    PageData<TbResource> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
    PageData<TbResource> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
 | 
			
		||||
        return resourceService.findAllTenantResources(tenantId, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,5 @@ public class TenantResourcesEdgeEventFetcher extends BasePageableEdgeEventFetche
 | 
			
		||||
        return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.TB_RESOURCE,
 | 
			
		||||
                EdgeEventActionType.ADDED, tbResource.getId(), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,9 @@ import org.thingsboard.server.dao.edge.EdgeEventService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
 | 
			
		||||
import org.thingsboard.server.dao.entityview.EntityViewService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationRuleService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTemplateService;
 | 
			
		||||
import org.thingsboard.server.dao.oauth2.OAuth2Service;
 | 
			
		||||
import org.thingsboard.server.dao.ota.OtaPackageService;
 | 
			
		||||
import org.thingsboard.server.dao.queue.QueueService;
 | 
			
		||||
@ -99,6 +102,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.dashboard.DashboardMs
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.device.DeviceMsgConstructorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.edge.EdgeMsgConstructor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.notification.NotificationMsgConstructor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.oauth2.OAuth2MsgConstructor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.queue.QueueMsgConstructorFactory;
 | 
			
		||||
@ -226,6 +230,15 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected ResourceService resourceService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected NotificationRuleService notificationRuleService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected NotificationTargetService notificationTargetService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected NotificationTemplateService notificationTemplateService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected OAuth2Service oAuth2Service;
 | 
			
		||||
 | 
			
		||||
@ -260,9 +273,13 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected EntityDataMsgConstructor entityDataMsgConstructor;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected NotificationMsgConstructor notificationMsgConstructor;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected OAuth2MsgConstructor oAuth2MsgConstructor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected RuleChainMsgConstructorFactory ruleChainMsgConstructorFactory;
 | 
			
		||||
 | 
			
		||||
@ -417,10 +434,8 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
        return switch (actionType) {
 | 
			
		||||
            case UPDATED, CREDENTIALS_UPDATED, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER, UPDATED_COMMENT ->
 | 
			
		||||
                    UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE;
 | 
			
		||||
            case ADDED, ASSIGNED_TO_EDGE, RELATION_ADD_OR_UPDATE, ADDED_COMMENT ->
 | 
			
		||||
                    UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE;
 | 
			
		||||
            case DELETED, UNASSIGNED_FROM_EDGE, RELATION_DELETED, DELETED_COMMENT, ALARM_DELETE ->
 | 
			
		||||
                    UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
 | 
			
		||||
            case ADDED, ASSIGNED_TO_EDGE, RELATION_ADD_OR_UPDATE, ADDED_COMMENT -> UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE;
 | 
			
		||||
            case DELETED, UNASSIGNED_FROM_EDGE, RELATION_DELETED, DELETED_COMMENT, ALARM_DELETE -> UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
 | 
			
		||||
            case ALARM_ACK -> UpdateMsgType.ALARM_ACK_RPC_MESSAGE;
 | 
			
		||||
            case ALARM_CLEAR -> UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE;
 | 
			
		||||
            default -> throw new RuntimeException("Unsupported actionType [" + actionType + "]");
 | 
			
		||||
@ -528,28 +543,21 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
 | 
			
		||||
    protected EntityId constructEntityId(String entityTypeStr, long entityIdMSB, long entityIdLSB) {
 | 
			
		||||
        EntityType entityType = EntityType.valueOf(entityTypeStr);
 | 
			
		||||
        switch (entityType) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
                return new DeviceId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case ASSET:
 | 
			
		||||
                return new AssetId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case ENTITY_VIEW:
 | 
			
		||||
                return new EntityViewId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case DASHBOARD:
 | 
			
		||||
                return new DashboardId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case TENANT:
 | 
			
		||||
                return TenantId.fromUUID(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case CUSTOMER:
 | 
			
		||||
                return new CustomerId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case USER:
 | 
			
		||||
                return new UserId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case EDGE:
 | 
			
		||||
                return new EdgeId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            default:
 | 
			
		||||
        return switch (entityType) {
 | 
			
		||||
            case DEVICE -> new DeviceId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case ASSET -> new AssetId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case ENTITY_VIEW -> new EntityViewId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case DASHBOARD -> new DashboardId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case TENANT -> TenantId.fromUUID(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case CUSTOMER -> new CustomerId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case USER -> new UserId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            case EDGE -> new EdgeId(new UUID(entityIdMSB, entityIdLSB));
 | 
			
		||||
            default -> {
 | 
			
		||||
                log.warn("Unsupported entity type [{}] during construct of entity id. entityIdMSB [{}], entityIdLSB [{}]",
 | 
			
		||||
                        entityTypeStr, entityIdMSB, entityIdLSB);
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
                yield null;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected UUID safeGetUUID(long mSB, long lSB) {
 | 
			
		||||
@ -570,8 +578,7 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
            case TENANT -> tenantService.findTenantById(tenantId) != null;
 | 
			
		||||
            case DEVICE -> deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId())) != null;
 | 
			
		||||
            case ASSET -> assetService.findAssetById(tenantId, new AssetId(entityId.getId())) != null;
 | 
			
		||||
            case ENTITY_VIEW ->
 | 
			
		||||
                    entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId())) != null;
 | 
			
		||||
            case ENTITY_VIEW -> entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId())) != null;
 | 
			
		||||
            case CUSTOMER -> customerService.findCustomerById(tenantId, new CustomerId(entityId.getId())) != null;
 | 
			
		||||
            case USER -> userService.findUserById(tenantId, new UserId(entityId.getId())) != null;
 | 
			
		||||
            case DASHBOARD -> dashboardService.findDashboardById(tenantId, new DashboardId(entityId.getId())) != null;
 | 
			
		||||
@ -599,9 +606,8 @@ public abstract class BaseEdgeProcessor {
 | 
			
		||||
        return metaData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void pushEntityEventToRuleEngine(TenantId tenantId, EntityId entityId, CustomerId customerId,
 | 
			
		||||
                                               TbMsgType msgType, String msgData, TbMsgMetaData metaData) {
 | 
			
		||||
        TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, msgData);
 | 
			
		||||
    protected void pushEntityEventToRuleEngine(TenantId tenantId, EntityId entityId, CustomerId customerId, String msgData, TbMsgMetaData metaData) {
 | 
			
		||||
        TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_CREATED, entityId, customerId, metaData, TbMsgDataType.JSON, msgData);
 | 
			
		||||
        tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, new TbQueueCallback() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(TbQueueMsgMetadata metadata) {
 | 
			
		||||
 | 
			
		||||
@ -31,16 +31,10 @@ public abstract class BaseEdgeProcessorFactory<T extends EdgeProcessor, U extend
 | 
			
		||||
    protected U v2Processor;
 | 
			
		||||
 | 
			
		||||
    public EdgeProcessor getProcessorByEdgeVersion(EdgeVersion edgeVersion) {
 | 
			
		||||
        switch (edgeVersion) {
 | 
			
		||||
            case V_3_3_0:
 | 
			
		||||
            case V_3_3_3:
 | 
			
		||||
            case V_3_4_0:
 | 
			
		||||
            case V_3_6_0:
 | 
			
		||||
            case V_3_6_1:
 | 
			
		||||
                return v1Processor;
 | 
			
		||||
            case V_3_6_2:
 | 
			
		||||
            default:
 | 
			
		||||
                return v2Processor;
 | 
			
		||||
        }
 | 
			
		||||
        return switch (edgeVersion) {
 | 
			
		||||
            case V_3_3_0, V_3_3_3, V_3_4_0, V_3_6_0, V_3_6_1 -> v1Processor;
 | 
			
		||||
            default -> v2Processor;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -156,4 +156,5 @@ public abstract class AlarmEdgeProcessor extends BaseAlarmProcessor implements A
 | 
			
		||||
        }
 | 
			
		||||
        return futures;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -58,15 +58,12 @@ public class AlarmEdgeProcessorV1 extends AlarmEdgeProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private EntityId getAlarmOriginator(TenantId tenantId, String entityName, EntityType entityType) {
 | 
			
		||||
        switch (entityType) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
                return deviceService.findDeviceByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            case ASSET:
 | 
			
		||||
                return assetService.findAssetByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            case ENTITY_VIEW:
 | 
			
		||||
                return entityViewService.findEntityViewByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            default:
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
        return switch (entityType) {
 | 
			
		||||
            case DEVICE -> deviceService.findDeviceByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            case ASSET -> assetService.findAssetByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            case ENTITY_VIEW -> entityViewService.findEntityViewByTenantIdAndName(tenantId, entityName).getId();
 | 
			
		||||
            default -> null;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,4 +40,5 @@ public class AlarmEdgeProcessorV2 extends AlarmEdgeProcessor {
 | 
			
		||||
    protected Alarm constructAlarmFromUpdateMsg(TenantId tenantId, AlarmId alarmId, EntityId originatorId, AlarmUpdateMsg alarmUpdateMsg) {
 | 
			
		||||
        return JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,4 +34,5 @@ public interface AlarmProcessor extends EdgeProcessor {
 | 
			
		||||
    ListenableFuture<Void> processAlarmCommentMsgFromEdge(TenantId tenantId, EdgeId edgeId, AlarmCommentUpdateMsg alarmCommentUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    DownlinkMsg convertAlarmCommentEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -144,23 +144,20 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        AlarmId alarmId = new AlarmId(entityId);
 | 
			
		||||
        UpdateMsgType msgType = getUpdateMsgType(actionType);
 | 
			
		||||
        switch (actionType) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ALARM_ACK:
 | 
			
		||||
            case ALARM_CLEAR:
 | 
			
		||||
            case ADDED, UPDATED, ALARM_ACK, ALARM_CLEAR -> {
 | 
			
		||||
                Alarm alarm = alarmService.findAlarmById(tenantId, alarmId);
 | 
			
		||||
                if (alarm != null) {
 | 
			
		||||
                    return ((AlarmMsgConstructor) alarmMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
			
		||||
                            .constructAlarmUpdatedMsg(msgType, alarm, findOriginatorEntityName(tenantId, alarm));
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ALARM_DELETE:
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case ALARM_DELETE, DELETED -> {
 | 
			
		||||
                Alarm deletedAlarm = JacksonUtil.convertValue(body, Alarm.class);
 | 
			
		||||
                if (deletedAlarm != null) {
 | 
			
		||||
                    return ((AlarmMsgConstructor) alarmMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
			
		||||
                            .constructAlarmUpdatedMsg(msgType, deletedAlarm, findOriginatorEntityName(tenantId, deletedAlarm));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
@ -168,25 +165,26 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
 | 
			
		||||
    private String findOriginatorEntityName(TenantId tenantId, Alarm alarm) {
 | 
			
		||||
        String entityName = null;
 | 
			
		||||
        switch (alarm.getOriginator().getEntityType()) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
            case DEVICE -> {
 | 
			
		||||
                Device deviceById = deviceService.findDeviceById(tenantId, new DeviceId(alarm.getOriginator().getId()));
 | 
			
		||||
                if (deviceById != null) {
 | 
			
		||||
                    entityName = deviceById.getName();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ASSET:
 | 
			
		||||
            }
 | 
			
		||||
            case ASSET -> {
 | 
			
		||||
                Asset assetById = assetService.findAssetById(tenantId, new AssetId(alarm.getOriginator().getId()));
 | 
			
		||||
                if (assetById != null) {
 | 
			
		||||
                    entityName = assetById.getName();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ENTITY_VIEW:
 | 
			
		||||
            }
 | 
			
		||||
            case ENTITY_VIEW -> {
 | 
			
		||||
                EntityView entityViewById = entityViewService.findEntityViewById(tenantId, new EntityViewId(alarm.getOriginator().getId()));
 | 
			
		||||
                if (entityViewById != null) {
 | 
			
		||||
                    entityName = entityViewById.getName();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return entityName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -97,7 +97,7 @@ public abstract class AssetEdgeProcessor extends BaseAssetProcessor implements A
 | 
			
		||||
            Asset asset = assetService.findAssetById(tenantId, assetId);
 | 
			
		||||
            String assetAsString = JacksonUtil.toString(asset);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, asset.getCustomerId());
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, assetId, asset.getCustomerId(), TbMsgType.ENTITY_CREATED, assetAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, assetId, asset.getCustomerId(), assetAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push asset action to rule engine: {}", tenantId, assetId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -56,4 +56,5 @@ public class AssetEdgeProcessorV1 extends AssetEdgeProcessor {
 | 
			
		||||
        CustomerId customerUUID = safeGetCustomerId(assetUpdateMsg.getCustomerIdMSB(), assetUpdateMsg.getCustomerIdLSB());
 | 
			
		||||
        asset.setCustomerId(customerUUID != null ? customerUUID : customerId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,4 +40,5 @@ public class AssetEdgeProcessorV2 extends AssetEdgeProcessor {
 | 
			
		||||
        CustomerId customerUUID = asset.getCustomerId() != null ? asset.getCustomerId() : customerId;
 | 
			
		||||
        asset.setCustomerId(customerUUID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,4 +30,5 @@ public interface AssetProcessor extends EdgeProcessor {
 | 
			
		||||
    ListenableFuture<Void> processAssetMsgFromEdge(TenantId tenantId, Edge edge, AssetUpdateMsg assetUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    DownlinkMsg convertAssetEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -72,4 +72,5 @@ public abstract class BaseAssetProcessor extends BaseEdgeProcessor {
 | 
			
		||||
    protected abstract Asset constructAssetFromUpdateMsg(TenantId tenantId, AssetId assetId, AssetUpdateMsg assetUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, Asset asset, AssetUpdateMsg assetUpdateMsg);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ public abstract class AssetProfileEdgeProcessor extends BaseAssetProfileProcesso
 | 
			
		||||
            AssetProfile assetProfile = assetProfileService.findAssetProfileById(tenantId, assetProfileId);
 | 
			
		||||
            String assetProfileAsString = JacksonUtil.toString(assetProfile);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, null);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, assetProfileId, null, TbMsgType.ENTITY_CREATED, assetProfileAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, assetProfileId, null, assetProfileAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push asset profile action to rule engine: {}", tenantId, assetProfileId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -52,8 +52,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        CustomerId customerId = new CustomerId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                Customer customer = customerService.findCustomerById(edgeEvent.getTenantId(), customerId);
 | 
			
		||||
                if (customer != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -64,15 +63,15 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addCustomerUpdateMsg(customerUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                CustomerUpdateMsg customerUpdateMsg = ((CustomerMsgConstructor)
 | 
			
		||||
                        customerMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructCustomerDeleteMsg(customerId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addCustomerUpdateMsg(customerUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
@ -97,4 +96,5 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                return Futures.immediateFuture(null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl
 | 
			
		||||
            Dashboard dashboard = dashboardService.findDashboardById(tenantId, dashboardId);
 | 
			
		||||
            String dashboardAsString = JacksonUtil.toString(dashboard);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, null);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, dashboardId, null, TbMsgType.ENTITY_CREATED, dashboardAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, dashboardId, null, dashboardAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push dashboard action to rule engine: {}", tenantId, dashboardId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,7 @@ public abstract class DeviceEdgeProcessor extends BaseDeviceProcessor implements
 | 
			
		||||
            Device device = deviceService.findDeviceById(tenantId, deviceId);
 | 
			
		||||
            String deviceAsString = JacksonUtil.toString(device);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, device.getCustomerId());
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, deviceId, device.getCustomerId(), TbMsgType.ENTITY_CREATED, deviceAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, deviceId, device.getCustomerId(), deviceAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push device action to rule engine: {}", tenantId, deviceId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
@ -286,4 +286,5 @@ public abstract class DeviceEdgeProcessor extends BaseDeviceProcessor implements
 | 
			
		||||
                .addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsg);
 | 
			
		||||
        return builder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ public abstract class DeviceProfileEdgeProcessor extends BaseDeviceProfileProces
 | 
			
		||||
            DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId);
 | 
			
		||||
            String deviceProfileAsString = JacksonUtil.toString(deviceProfile);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, null);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, deviceProfileId, null, TbMsgType.ENTITY_CREATED, deviceProfileAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, deviceProfileId, null, deviceProfileAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push device profile action to rule engine: {}", tenantId, deviceProfileId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -50,8 +50,7 @@ public class EdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        EdgeId edgeId = new EdgeId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ASSIGNED_TO_CUSTOMER:
 | 
			
		||||
            case UNASSIGNED_FROM_CUSTOMER:
 | 
			
		||||
            case ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> {
 | 
			
		||||
                Edge edge = edgeService.findEdgeById(edgeEvent.getTenantId(), edgeId);
 | 
			
		||||
                if (edge != null) {
 | 
			
		||||
                    EdgeConfiguration edgeConfigMsg =
 | 
			
		||||
@ -61,7 +60,7 @@ public class EdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .setEdgeConfiguration(edgeConfigMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
@ -112,4 +111,5 @@ public class EdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
            return Futures.immediateFailedFuture(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -95,7 +95,7 @@ public abstract class EntityViewEdgeProcessor extends BaseEntityViewProcessor im
 | 
			
		||||
            EntityView entityView = entityViewService.findEntityViewById(tenantId, entityViewId);
 | 
			
		||||
            String entityViewAsString = JacksonUtil.toString(entityView);
 | 
			
		||||
            TbMsgMetaData msgMetaData = getEdgeActionTbMsgMetaData(edge, entityView.getCustomerId());
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, entityViewId, entityView.getCustomerId(), TbMsgType.ENTITY_CREATED, entityViewAsString, msgMetaData);
 | 
			
		||||
            pushEntityEventToRuleEngine(tenantId, entityViewId, entityView.getCustomerId(), entityViewAsString, msgMetaData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("[{}][{}] Failed to push entity view action to rule engine: {}", tenantId, entityViewId, TbMsgType.ENTITY_CREATED.name(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -62,4 +62,5 @@ public class EntityViewProcessorV1 extends EntityViewEdgeProcessor {
 | 
			
		||||
        CustomerId customerUUID = safeGetCustomerId(entityViewUpdateMsg.getCustomerIdMSB(), entityViewUpdateMsg.getCustomerIdLSB());
 | 
			
		||||
        entityView.setCustomerId(customerUUID != null ? customerUUID : customerId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,4 +40,5 @@ public class EntityViewProcessorV2 extends EntityViewEdgeProcessor {
 | 
			
		||||
        CustomerId customerUUID = entityView.getCustomerId() != null ? entityView.getCustomerId() : customerId;
 | 
			
		||||
        entityView.setCustomerId(customerUUID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,119 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2024 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.edge.rpc.processor.notification;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationRuleId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTemplateId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Component
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
public class NotificationEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
 | 
			
		||||
    public DownlinkMsg convertNotificationRuleToDownlink(EdgeEvent edgeEvent) {
 | 
			
		||||
        NotificationRuleId notificationRuleId = new NotificationRuleId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                NotificationRule notificationRule = notificationRuleService.findNotificationRuleById(edgeEvent.getTenantId(), notificationRuleId);
 | 
			
		||||
                if (notificationRule != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
                    NotificationRuleUpdateMsg notificationRuleUpdateMsg = notificationMsgConstructor.constructNotificationRuleUpdateMsg(msgType, notificationRule);
 | 
			
		||||
                    downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                            .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                            .addNotificationRuleUpdateMsg(notificationRuleUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                NotificationRuleUpdateMsg notificationRuleUpdateMsg = notificationMsgConstructor.constructNotificationRuleDeleteMsg(notificationRuleId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addNotificationRuleUpdateMsg(notificationRuleUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DownlinkMsg convertNotificationTargetToDownlink(EdgeEvent edgeEvent) {
 | 
			
		||||
        NotificationTargetId notificationTargetId = new NotificationTargetId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                NotificationTarget notificationTarget = notificationTargetService.findNotificationTargetById(edgeEvent.getTenantId(), notificationTargetId);
 | 
			
		||||
                if (notificationTarget != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
                    NotificationTargetUpdateMsg notificationTargetUpdateMsg = notificationMsgConstructor.constructNotificationTargetUpdateMsg(msgType, notificationTarget);
 | 
			
		||||
                    downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                            .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                            .addNotificationTargetUpdateMsg(notificationTargetUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                NotificationTargetUpdateMsg notificationTargetUpdateMsg = notificationMsgConstructor.constructNotificationTargetDeleteMsg(notificationTargetId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addNotificationTargetUpdateMsg(notificationTargetUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DownlinkMsg convertNotificationTemplateToDownlink(EdgeEvent edgeEvent) {
 | 
			
		||||
        NotificationTemplateId notificationTemplateId = new NotificationTemplateId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                NotificationTemplate notificationTemplate = notificationTemplateService.findNotificationTemplateById(edgeEvent.getTenantId(), notificationTemplateId);
 | 
			
		||||
                if (notificationTemplate != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
                    NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = notificationMsgConstructor.constructNotificationTemplateUpdateMsg(msgType, notificationTemplate);
 | 
			
		||||
                    downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                            .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                            .addNotificationTemplateUpdateMsg(notificationTemplateUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = notificationMsgConstructor.constructNotificationTemplateDeleteMsg(notificationTemplateId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addNotificationTemplateUpdateMsg(notificationTemplateUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -38,8 +38,7 @@ public class OtaPackageEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        OtaPackageId otaPackageId = new OtaPackageId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                OtaPackage otaPackage = otaPackageService.findOtaPackageById(edgeEvent.getTenantId(), otaPackageId);
 | 
			
		||||
                if (otaPackage != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -50,16 +49,17 @@ public class OtaPackageEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addOtaPackageUpdateMsg(otaPackageUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                OtaPackageUpdateMsg otaPackageUpdateMsg = ((OtaPackageMsgConstructor)
 | 
			
		||||
                        otaPackageMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructOtaPackageDeleteMsg(otaPackageId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addOtaPackageUpdateMsg(otaPackageUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,8 +38,7 @@ public class QueueEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        QueueId queueId = new QueueId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                Queue queue = queueService.findQueueById(edgeEvent.getTenantId(), queueId);
 | 
			
		||||
                if (queue != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -50,16 +49,17 @@ public class QueueEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addQueueUpdateMsg(queueUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                QueueUpdateMsg queueDeleteMsg = ((QueueMsgConstructor)
 | 
			
		||||
                        queueMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructQueueDeleteMsg(queueId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addQueueUpdateMsg(queueDeleteMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -58,4 +58,5 @@ public abstract class BaseRelationProcessor extends BaseEdgeProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract EntityRelation constructEntityRelationFromUpdateMsg(RelationUpdateMsg relationUpdateMsg);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -91,4 +91,5 @@ public abstract class RelationEdgeProcessor extends BaseRelationProcessor implem
 | 
			
		||||
        }
 | 
			
		||||
        return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -49,4 +49,5 @@ public class RelationEdgeProcessorV1 extends RelationEdgeProcessor {
 | 
			
		||||
        entityRelation.setAdditionalInfo(JacksonUtil.toJsonNode(relationUpdateMsg.getAdditionalInfo()));
 | 
			
		||||
        return entityRelation;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,4 +31,5 @@ public class RelationEdgeProcessorV2 extends RelationEdgeProcessor {
 | 
			
		||||
    protected EntityRelation constructEntityRelationFromUpdateMsg(RelationUpdateMsg relationUpdateMsg) {
 | 
			
		||||
        return JacksonUtil.fromString(relationUpdateMsg.getEntity(), EntityRelation.class, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,4 +29,5 @@ public interface RelationProcessor extends EdgeProcessor {
 | 
			
		||||
    ListenableFuture<Void> processRelationMsgFromEdge(TenantId tenantId, Edge edge, RelationUpdateMsg relationUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    DownlinkMsg convertRelationEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -72,4 +72,5 @@ public abstract class BaseResourceProcessor extends BaseEdgeProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract TbResource constructResourceFromUpdateMsg(TenantId tenantId, TbResourceId tbResourceId, ResourceUpdateMsg resourceUpdateMsg);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -74,8 +74,7 @@ public abstract class ResourceEdgeProcessor extends BaseResourceProcessor implem
 | 
			
		||||
        TbResourceId tbResourceId = new TbResourceId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                TbResource tbResource = resourceService.findResourceById(edgeEvent.getTenantId(), tbResourceId);
 | 
			
		||||
                if (tbResource != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -86,16 +85,17 @@ public abstract class ResourceEdgeProcessor extends BaseResourceProcessor implem
 | 
			
		||||
                            .addResourceUpdateMsg(resourceUpdateMsg)
 | 
			
		||||
                            .build() : null;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                ResourceUpdateMsg resourceUpdateMsg = ((ResourceMsgConstructor)
 | 
			
		||||
                        resourceMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructResourceDeleteMsg(tbResourceId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addResourceUpdateMsg(resourceUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,4 +45,5 @@ public class ResourceEdgeProcessorV1 extends ResourceEdgeProcessor {
 | 
			
		||||
        resource.setEtag(resourceUpdateMsg.hasEtag() ? resourceUpdateMsg.getEtag() : null);
 | 
			
		||||
        return resource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,4 +33,5 @@ public class ResourceEdgeProcessorV2 extends ResourceEdgeProcessor {
 | 
			
		||||
    protected TbResource constructResourceFromUpdateMsg(TenantId tenantId, TbResourceId tbResourceId, ResourceUpdateMsg resourceUpdateMsg) {
 | 
			
		||||
        return JacksonUtil.fromString(resourceUpdateMsg.getEntity(), TbResource.class, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,4 +29,5 @@ public interface ResourceProcessor extends EdgeProcessor {
 | 
			
		||||
    ListenableFuture<Void> processResourceMsgFromEdge(TenantId tenantId, Edge edge, ResourceUpdateMsg resourceUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    DownlinkMsg convertResourceEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -43,16 +43,15 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ASSIGNED_TO_EDGE:
 | 
			
		||||
            case ADDED, UPDATED, ASSIGNED_TO_EDGE -> {
 | 
			
		||||
                RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId);
 | 
			
		||||
                if (ruleChain != null) {
 | 
			
		||||
                    boolean isRoot = false;
 | 
			
		||||
                    if (edgeEvent.getBody() != null && edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY) != null) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            isRoot = Boolean.parseBoolean(edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY).asText());
 | 
			
		||||
                        } catch (Exception ignored) {}
 | 
			
		||||
                        } catch (Exception ignored) {
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!isRoot) {
 | 
			
		||||
                        Edge edge = edgeService.findEdgeById(edgeEvent.getTenantId(), edgeEvent.getEdgeId());
 | 
			
		||||
@ -67,15 +66,12 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addRuleChainUpdateMsg(ruleChainUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            case UNASSIGNED_FROM_EDGE:
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addRuleChainUpdateMsg(((RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
			
		||||
                                .constructRuleChainDeleteMsg(ruleChainId))
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                    .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                    .addRuleChainUpdateMsg(((RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
			
		||||
                            .constructRuleChainDeleteMsg(ruleChainId))
 | 
			
		||||
                    .build();
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
@ -99,4 +95,5 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,4 +45,5 @@ public class AdminSettingsEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                .addAdminSettingsUpdateMsg(adminSettingsUpdateMsg)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -138,41 +138,39 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        TbMsgMetaData metaData = new TbMsgMetaData();
 | 
			
		||||
        CustomerId customerId = null;
 | 
			
		||||
        switch (entityId.getEntityType()) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
            case DEVICE -> {
 | 
			
		||||
                Device device = deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId()));
 | 
			
		||||
                if (device != null) {
 | 
			
		||||
                    customerId = device.getCustomerId();
 | 
			
		||||
                    metaData.putValue("deviceName", device.getName());
 | 
			
		||||
                    metaData.putValue("deviceType", device.getType());
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ASSET:
 | 
			
		||||
            }
 | 
			
		||||
            case ASSET -> {
 | 
			
		||||
                Asset asset = assetService.findAssetById(tenantId, new AssetId(entityId.getId()));
 | 
			
		||||
                if (asset != null) {
 | 
			
		||||
                    customerId = asset.getCustomerId();
 | 
			
		||||
                    metaData.putValue("assetName", asset.getName());
 | 
			
		||||
                    metaData.putValue("assetType", asset.getType());
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ENTITY_VIEW:
 | 
			
		||||
            }
 | 
			
		||||
            case ENTITY_VIEW -> {
 | 
			
		||||
                EntityView entityView = entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId()));
 | 
			
		||||
                if (entityView != null) {
 | 
			
		||||
                    customerId = entityView.getCustomerId();
 | 
			
		||||
                    metaData.putValue("entityViewName", entityView.getName());
 | 
			
		||||
                    metaData.putValue("entityViewType", entityView.getType());
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case EDGE:
 | 
			
		||||
            }
 | 
			
		||||
            case EDGE -> {
 | 
			
		||||
                Edge edge = edgeService.findEdgeById(tenantId, new EdgeId(entityId.getId()));
 | 
			
		||||
                if (edge != null) {
 | 
			
		||||
                    customerId = edge.getCustomerId();
 | 
			
		||||
                    metaData.putValue("edgeName", edge.getName());
 | 
			
		||||
                    metaData.putValue("edgeType", edge.getType());
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                log.debug("[{}] Using empty metadata for entityId [{}]", tenantId, entityId);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default -> log.debug("[{}] Using empty metadata for entityId [{}]", tenantId, entityId);
 | 
			
		||||
        }
 | 
			
		||||
        return new ImmutablePair<>(metaData, customerId != null ? customerId : new CustomerId(ModelConstants.NULL_UUID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -53,4 +53,5 @@ public class TenantProfileEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -39,8 +39,7 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        UserId userId = new UserId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                User user = userService.findUserById(edgeEvent.getTenantId(), userId);
 | 
			
		||||
                if (user != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -49,14 +48,12 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserUpdatedMsg(msgType, user))
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserDeleteMsg(userId))
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            case CREDENTIALS_UPDATED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                    .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                    .addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserDeleteMsg(userId))
 | 
			
		||||
                    .build();
 | 
			
		||||
            case CREDENTIALS_UPDATED -> {
 | 
			
		||||
                UserCredentials userCredentialsByUserId = userService.findUserCredentialsByUserId(edgeEvent.getTenantId(), userId);
 | 
			
		||||
                if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) {
 | 
			
		||||
                    UserCredentialsUpdateMsg userCredentialsUpdateMsg =
 | 
			
		||||
@ -66,8 +63,9 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addUserCredentialsUpdateMsg(userCredentialsUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,8 +40,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId);
 | 
			
		||||
                if (widgetsBundle != null) {
 | 
			
		||||
                    List<String> widgets = widgetTypeService.findWidgetFqnsByWidgetsBundleId(edgeEvent.getTenantId(), widgetsBundleId);
 | 
			
		||||
@ -53,16 +52,17 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
 | 
			
		||||
                        ((WidgetMsgConstructor) widgetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructWidgetsBundleDeleteMsg(widgetsBundleId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,8 +38,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId());
 | 
			
		||||
        DownlinkMsg downlinkMsg = null;
 | 
			
		||||
        switch (edgeEvent.getAction()) {
 | 
			
		||||
            case ADDED:
 | 
			
		||||
            case UPDATED:
 | 
			
		||||
            case ADDED, UPDATED -> {
 | 
			
		||||
                WidgetTypeDetails widgetTypeDetails = widgetTypeService.findWidgetTypeDetailsById(edgeEvent.getTenantId(), widgetTypeId);
 | 
			
		||||
                if (widgetTypeDetails != null) {
 | 
			
		||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
			
		||||
@ -50,16 +49,17 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor {
 | 
			
		||||
                            .addWidgetTypeUpdateMsg(widgetTypeUpdateMsg)
 | 
			
		||||
                            .build();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case DELETED:
 | 
			
		||||
            }
 | 
			
		||||
            case DELETED -> {
 | 
			
		||||
                WidgetTypeUpdateMsg widgetTypeUpdateMsg =
 | 
			
		||||
                        ((WidgetMsgConstructor) widgetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructWidgetTypeDeleteMsg(widgetTypeId);
 | 
			
		||||
                downlinkMsg = DownlinkMsg.newBuilder()
 | 
			
		||||
                        .setDownlinkMsgId(EdgeUtils.nextPositiveInt())
 | 
			
		||||
                        .addWidgetTypeUpdateMsg(widgetTypeUpdateMsg)
 | 
			
		||||
                        .build();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return downlinkMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.common.data.AttributeScope;
 | 
			
		||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
@ -110,9 +109,6 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private DbCallbackExecutorService dbCallbackExecutorService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private TbClusterService tbClusterService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
 | 
			
		||||
        log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg);
 | 
			
		||||
@ -292,8 +288,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
 | 
			
		||||
        return futureToSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ListenableFuture<List<EntityRelation>> findRelationByQuery(TenantId tenantId, Edge edge,
 | 
			
		||||
                                                                       EntityId entityId, EntitySearchDirection direction) {
 | 
			
		||||
    private ListenableFuture<List<EntityRelation>> findRelationByQuery(TenantId tenantId, Edge edge, EntityId entityId, EntitySearchDirection direction) {
 | 
			
		||||
        EntityRelationsQuery query = new EntityRelationsQuery();
 | 
			
		||||
        query.setParameters(new RelationsSearchParameters(entityId, direction, 1, false));
 | 
			
		||||
        return relationService.findByQuery(tenantId, query);
 | 
			
		||||
 | 
			
		||||
@ -247,7 +247,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
    private void processForTarget(NotificationTarget target, NotificationProcessingContext ctx) {
 | 
			
		||||
        Iterable<? extends NotificationRecipient> recipients;
 | 
			
		||||
        switch (target.getConfiguration().getType()) {
 | 
			
		||||
            case PLATFORM_USERS: {
 | 
			
		||||
            case PLATFORM_USERS -> {
 | 
			
		||||
                PlatformUsersNotificationTargetConfig targetConfig = (PlatformUsersNotificationTargetConfig) target.getConfiguration();
 | 
			
		||||
                if (targetConfig.getUsersFilter().getType().isForRules() && ctx.getRequest().getInfo() instanceof RuleOriginatedNotificationInfo) {
 | 
			
		||||
                    recipients = new PageDataIterable<>(pageLink -> {
 | 
			
		||||
@ -258,21 +258,16 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
                        return notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink);
 | 
			
		||||
                    }, 256);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case SLACK: {
 | 
			
		||||
            case SLACK -> {
 | 
			
		||||
                SlackNotificationTargetConfig targetConfig = (SlackNotificationTargetConfig) target.getConfiguration();
 | 
			
		||||
                recipients = List.of(targetConfig.getConversation());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case MICROSOFT_TEAMS: {
 | 
			
		||||
            case MICROSOFT_TEAMS -> {
 | 
			
		||||
                MicrosoftTeamsNotificationTargetConfig targetConfig = (MicrosoftTeamsNotificationTargetConfig) target.getConfiguration();
 | 
			
		||||
                recipients = List.of(targetConfig);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default: {
 | 
			
		||||
                recipients = Collections.emptyList();
 | 
			
		||||
            }
 | 
			
		||||
            default -> recipients = Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Set<NotificationDeliveryMethod> deliveryMethods = new HashSet<>(ctx.getDeliveryMethods());
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,9 @@ import org.thingsboard.server.dao.edge.EdgeEventService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeService;
 | 
			
		||||
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
 | 
			
		||||
import org.thingsboard.server.dao.entityview.EntityViewService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationRuleService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTemplateService;
 | 
			
		||||
import org.thingsboard.server.dao.oauth2.OAuth2Service;
 | 
			
		||||
import org.thingsboard.server.dao.ota.OtaPackageService;
 | 
			
		||||
import org.thingsboard.server.dao.queue.QueueService;
 | 
			
		||||
@ -82,6 +85,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.edge.EdgeMsgConstruct
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV1;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV2;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.notification.NotificationMsgConstructor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.oauth2.OAuth2MsgConstructor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorV1;
 | 
			
		||||
@ -130,6 +134,7 @@ import org.thingsboard.server.service.edge.rpc.processor.device.profile.DevicePr
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV1;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV2;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorFactory;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorV1;
 | 
			
		||||
@ -197,6 +202,15 @@ public abstract class BaseEdgeProcessorTest {
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected UserService userService;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected NotificationRuleService notificationRuleService;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected NotificationTargetService notificationTargetService;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected NotificationTemplateService notificationTemplateService;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected DeviceProfileService deviceProfileService;
 | 
			
		||||
 | 
			
		||||
@ -366,6 +380,9 @@ public abstract class BaseEdgeProcessorTest {
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected WidgetMsgConstructorV2 widgetMsgConstructorV2;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected NotificationMsgConstructor notificationMsgConstructor;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected OAuth2MsgConstructor oAuth2MsgConstructor;
 | 
			
		||||
 | 
			
		||||
@ -429,6 +446,9 @@ public abstract class BaseEdgeProcessorTest {
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected OAuth2EdgeProcessor oAuth2EdgeProcessor;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    protected NotificationEdgeProcessor notificationEdgeProcessor;
 | 
			
		||||
 | 
			
		||||
    @SpyBean
 | 
			
		||||
    protected RuleChainMsgConstructorFactory ruleChainMsgConstructorFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,9 @@ public enum EdgeEventType {
 | 
			
		||||
    ADMIN_SETTINGS(true, null),
 | 
			
		||||
    OTA_PACKAGE(true, EntityType.OTA_PACKAGE),
 | 
			
		||||
    QUEUE(true, EntityType.QUEUE),
 | 
			
		||||
    NOTIFICATION_RULE (true, EntityType.NOTIFICATION_RULE),
 | 
			
		||||
    NOTIFICATION_TARGET (true, EntityType.NOTIFICATION_TARGET),
 | 
			
		||||
    NOTIFICATION_TEMPLATE (true, EntityType.NOTIFICATION_TEMPLATE),
 | 
			
		||||
    TB_RESOURCE(true, EntityType.TB_RESOURCE),
 | 
			
		||||
    OAUTH2(true, null);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -147,6 +147,12 @@ public class EntityIdFactory {
 | 
			
		||||
                return new QueueId(uuid);
 | 
			
		||||
            case TB_RESOURCE:
 | 
			
		||||
                return new TbResourceId(uuid);
 | 
			
		||||
            case NOTIFICATION_RULE:
 | 
			
		||||
                return new NotificationRuleId(uuid);
 | 
			
		||||
            case NOTIFICATION_TARGET:
 | 
			
		||||
                return new NotificationTargetId(uuid);
 | 
			
		||||
            case NOTIFICATION_TEMPLATE:
 | 
			
		||||
                return new NotificationTemplateId(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        throw new IllegalArgumentException("EdgeEventType " + edgeEventType + " is not supported!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -472,6 +472,27 @@ message OAuth2UpdateMsg {
 | 
			
		||||
  string entity = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message NotificationRuleUpdateMsg {
 | 
			
		||||
  UpdateMsgType msgType = 1;
 | 
			
		||||
  int64 idMSB = 2;
 | 
			
		||||
  int64 idLSB = 3;
 | 
			
		||||
  optional string entity = 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message NotificationTargetUpdateMsg {
 | 
			
		||||
  UpdateMsgType msgType = 1;
 | 
			
		||||
  int64 idMSB = 2;
 | 
			
		||||
  int64 idLSB = 3;
 | 
			
		||||
  optional string entity = 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message NotificationTemplateUpdateMsg {
 | 
			
		||||
  UpdateMsgType msgType = 1;
 | 
			
		||||
  int64 idMSB = 2;
 | 
			
		||||
  int64 idLSB = 3;
 | 
			
		||||
  optional string entity = 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message RuleChainMetadataRequestMsg {
 | 
			
		||||
  int64 ruleChainIdMSB = 1;
 | 
			
		||||
  int64 ruleChainIdLSB = 2;
 | 
			
		||||
@ -674,5 +695,8 @@ message DownlinkMsg {
 | 
			
		||||
  repeated ResourceUpdateMsg resourceUpdateMsg = 28;
 | 
			
		||||
  repeated AlarmCommentUpdateMsg alarmCommentUpdateMsg = 29;
 | 
			
		||||
  repeated OAuth2UpdateMsg oAuth2UpdateMsg = 30;
 | 
			
		||||
  repeated NotificationRuleUpdateMsg notificationRuleUpdateMsg = 31;
 | 
			
		||||
  repeated NotificationTargetUpdateMsg notificationTargetUpdateMsg = 32;
 | 
			
		||||
  repeated NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = 33;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,8 @@ import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
 | 
			
		||||
import org.thingsboard.server.dao.entity.EntityDaoService;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
 | 
			
		||||
import org.thingsboard.server.dao.user.UserService;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -65,7 +67,10 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTarget saveNotificationTarget(TenantId tenantId, NotificationTarget notificationTarget) {
 | 
			
		||||
        try {
 | 
			
		||||
            return notificationTargetDao.saveAndFlush(tenantId, notificationTarget);
 | 
			
		||||
            NotificationTarget savedTarget = notificationTargetDao.saveAndFlush(tenantId, notificationTarget);
 | 
			
		||||
            eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedTarget.getId())
 | 
			
		||||
                    .created(notificationTarget.getId() == null).build());
 | 
			
		||||
            return savedTarget;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            checkConstraintViolation(e, Map.of(
 | 
			
		||||
                    "uq_notification_target_name", "Recipients group with such name already exists"
 | 
			
		||||
@ -158,19 +163,21 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<User> findRecipientsForRuleNotificationTargetConfig(TenantId tenantId, PlatformUsersNotificationTargetConfig targetConfig, RuleOriginatedNotificationInfo info, PageLink pageLink) {
 | 
			
		||||
        switch (targetConfig.getUsersFilter().getType()) {
 | 
			
		||||
            case ORIGINATOR_ENTITY_OWNER_USERS:
 | 
			
		||||
            case ORIGINATOR_ENTITY_OWNER_USERS -> {
 | 
			
		||||
                CustomerId customerId = info.getAffectedCustomerId();
 | 
			
		||||
                if (customerId != null && !customerId.isNullUid()) {
 | 
			
		||||
                    return userService.findCustomerUsers(tenantId, customerId, pageLink);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return userService.findTenantAdmins(tenantId, pageLink);
 | 
			
		||||
                }
 | 
			
		||||
            case AFFECTED_USER:
 | 
			
		||||
            }
 | 
			
		||||
            case AFFECTED_USER -> {
 | 
			
		||||
                UserId userId = info.getAffectedUserId();
 | 
			
		||||
                if (userId != null) {
 | 
			
		||||
                    return new PageData<>(List.of(userService.findUserById(tenantId, userId)), 1, 1, false);
 | 
			
		||||
                }
 | 
			
		||||
            case AFFECTED_TENANT_ADMINISTRATORS:
 | 
			
		||||
            }
 | 
			
		||||
            case AFFECTED_TENANT_ADMINISTRATORS -> {
 | 
			
		||||
                TenantId affectedTenantId = info.getAffectedTenantId();
 | 
			
		||||
                if (affectedTenantId == null) {
 | 
			
		||||
                    affectedTenantId = tenantId;
 | 
			
		||||
@ -178,9 +185,8 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
 | 
			
		||||
                if (!affectedTenantId.isNullUid()) {
 | 
			
		||||
                    return userService.findTenantAdmins(affectedTenantId, pageLink);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IllegalArgumentException("Recipient type not supported");
 | 
			
		||||
            }
 | 
			
		||||
            default -> throw new IllegalArgumentException("Recipient type not supported");
 | 
			
		||||
        }
 | 
			
		||||
        return new PageData<>();
 | 
			
		||||
    }
 | 
			
		||||
@ -194,6 +200,7 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
 | 
			
		||||
            throw new IllegalArgumentException("Recipients group is being used in notification rule");
 | 
			
		||||
        }
 | 
			
		||||
        notificationTargetDao.removeById(tenantId, id.getId());
 | 
			
		||||
        eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(id).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,8 @@ import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
 | 
			
		||||
import org.thingsboard.server.dao.entity.EntityDaoService;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
@ -55,7 +57,10 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            return notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
 | 
			
		||||
            NotificationTemplate savedTemplate = notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
 | 
			
		||||
            eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedTemplate.getId())
 | 
			
		||||
                    .created(notificationTemplate.getId() == null).build());
 | 
			
		||||
            return savedTemplate;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            checkConstraintViolation(e, Map.of(
 | 
			
		||||
                    "uq_notification_template_name", "Notification template with such name already exists"
 | 
			
		||||
@ -82,6 +87,7 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
 | 
			
		||||
            ));
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
        eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(id).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user