38 changed files with 458 additions and 87 deletions
@ -0,0 +1,53 @@ |
|||
/** |
|||
* 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.notification.rule.trigger; |
|||
|
|||
import org.apache.commons.lang3.exception.ExceptionUtils; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.housekeeper.HousekeeperTask; |
|||
import org.thingsboard.server.common.data.notification.info.TaskProcessingFailureNotificationInfo; |
|||
import org.thingsboard.server.common.data.notification.rule.trigger.TaskProcessingFailureTrigger; |
|||
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; |
|||
import org.thingsboard.server.common.data.notification.rule.trigger.config.TaskProcessingFailureNotificationRuleTriggerConfig; |
|||
|
|||
@Service |
|||
public class TaskProcessingFailureTriggerProcessor implements NotificationRuleTriggerProcessor<TaskProcessingFailureTrigger, TaskProcessingFailureNotificationRuleTriggerConfig> { |
|||
|
|||
@Override |
|||
public boolean matchesFilter(TaskProcessingFailureTrigger trigger, TaskProcessingFailureNotificationRuleTriggerConfig triggerConfig) { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public TaskProcessingFailureNotificationInfo constructNotificationInfo(TaskProcessingFailureTrigger trigger) { |
|||
HousekeeperTask task = trigger.getTask(); |
|||
return TaskProcessingFailureNotificationInfo.builder() |
|||
.tenantId(task.getTenantId()) |
|||
.entityId(task.getEntityId()) |
|||
.taskType(task.getTaskType()) |
|||
.taskDescription(task.getDescription()) |
|||
.error(StringUtils.truncate(ExceptionUtils.getStackTrace(trigger.getError()), 1024)) |
|||
.attempt(trigger.getAttempt()) |
|||
.build(); |
|||
} |
|||
|
|||
@Override |
|||
public NotificationRuleTriggerType getTriggerType() { |
|||
return NotificationRuleTriggerType.TASK_PROCESSING_FAILURE; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
/** |
|||
* 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.common.data.housekeeper; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public enum HousekeeperTaskType { |
|||
|
|||
DELETE_ENTITIES("entities deletion"), |
|||
DELETE_ATTRIBUTES("attributes deletion"), |
|||
DELETE_TELEMETRY("telemetry deletion"), |
|||
DELETE_EVENTS("events deletion"), |
|||
UNASSIGN_ALARMS("alarms unassigning"), |
|||
DELETE_ENTITY_ALARMS("entity alarms deletion"); |
|||
|
|||
private final String description; |
|||
|
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
/** |
|||
* 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.common.data.notification.info; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
import java.util.Map; |
|||
|
|||
import static org.thingsboard.server.common.data.util.CollectionsUtil.mapOf; |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Builder |
|||
public class TaskProcessingFailureNotificationInfo implements RuleOriginatedNotificationInfo { |
|||
|
|||
private TenantId tenantId; |
|||
private EntityId entityId; |
|||
private HousekeeperTaskType taskType; |
|||
private String taskDescription; |
|||
private String error; |
|||
private int attempt; |
|||
|
|||
@Override |
|||
public Map<String, String> getTemplateData() { |
|||
return mapOf( |
|||
"tenantId", tenantId.toString(), |
|||
"entityType", entityId.getEntityType().getNormalName(), |
|||
"entityId", entityId.getId().toString(), |
|||
"taskType", taskType.getDescription(), |
|||
"taskDescription", taskDescription, |
|||
"error", error, |
|||
"attempt", String.valueOf(attempt) |
|||
); |
|||
} |
|||
|
|||
@Override |
|||
public TenantId getAffectedTenantId() { |
|||
return tenantId; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
/** |
|||
* 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.common.data.notification.rule.trigger; |
|||
|
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import org.thingsboard.server.common.data.housekeeper.HousekeeperTask; |
|||
import org.thingsboard.server.common.data.id.EntityId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; |
|||
|
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
@Data |
|||
@Builder |
|||
public class TaskProcessingFailureTrigger implements NotificationRuleTrigger { |
|||
|
|||
private final HousekeeperTask task; |
|||
private final int attempt; |
|||
private final Throwable error; |
|||
|
|||
@Override |
|||
public NotificationRuleTriggerType getType() { |
|||
return NotificationRuleTriggerType.TASK_PROCESSING_FAILURE; |
|||
} |
|||
|
|||
@Override |
|||
public TenantId getTenantId() { |
|||
return task.getTenantId(); |
|||
} |
|||
|
|||
@Override |
|||
public EntityId getOriginatorEntityId() { |
|||
return task.getEntityId(); |
|||
} |
|||
|
|||
@Override |
|||
public boolean deduplicate() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public String getDeduplicationKey() { |
|||
return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), task.getTaskType().toString()); |
|||
} |
|||
|
|||
@Override |
|||
public long getDefaultDeduplicationDuration() { |
|||
return TimeUnit.MINUTES.toMillis(30); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
#### Task processing failure notification templatization |
|||
|
|||
<div class="divider"></div> |
|||
<br/> |
|||
|
|||
Notification subject and message fields support templatization. |
|||
The list of available templatization parameters depends on the template type. |
|||
See the available types and parameters below: |
|||
|
|||
Available template parameters: |
|||
|
|||
* `taskType` - the task type, e.g. 'telemetry deletion'; |
|||
* `taskDescription` - the task description, e.g. 'telemetry deletion for device c4d93dc0-63a1-11ee-aa6d-f7cbc0a71325'; |
|||
* `error` - the error stacktrace |
|||
* `tenantId` - the tenant id; |
|||
* `entityType` - the type of the entity to which the task is related; |
|||
* `entityId` - the id of the entity to which the task is related; |
|||
* `attempt` - the number of attempts processing the task |
|||
|
|||
Parameter names must be wrapped using `${...}`. For example: `${entityType}`. |
|||
You may also modify the value of the parameter with one of the suffixes: |
|||
|
|||
* `upperCase`, for example - `${entityType:upperCase}` |
|||
* `lowerCase`, for example - `${entityType:lowerCase}` |
|||
* `capitalize`, for example - `${entityType:capitalize}` |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
##### Examples |
|||
|
|||
Let's assume that telemetry deletion failed for some device. |
|||
The following template: |
|||
|
|||
```text |
|||
Failed to process ${taskType} for ${entityType:lowerCase} ${entityId} |
|||
{:copy-code} |
|||
``` |
|||
|
|||
will be transformed to: |
|||
|
|||
```text |
|||
Failed to process telemetry deletion for device c4d93dc0-63a1-11ee-aa6d-f7cbc0a71325 |
|||
``` |
|||
|
|||
<br> |
|||
<br> |
|||
Loading…
Reference in new issue