|
|
|
@ -16,6 +16,7 @@ |
|
|
|
package org.thingsboard.server.controller; |
|
|
|
|
|
|
|
import io.swagger.annotations.ApiOperation; |
|
|
|
import io.swagger.annotations.ApiParam; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.security.access.prepost.PreAuthorize; |
|
|
|
@ -76,6 +77,16 @@ import java.util.Set; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_START; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; |
|
|
|
import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; |
|
|
|
import static org.thingsboard.server.service.security.permission.Resource.NOTIFICATION; |
|
|
|
|
|
|
|
@RestController |
|
|
|
@ -93,7 +104,10 @@ public class NotificationController extends BaseController { |
|
|
|
private final NotificationSettingsService notificationSettingsService; |
|
|
|
|
|
|
|
@ApiOperation(value = "Get notifications (getNotifications)", |
|
|
|
notes = "**WebSocket API**:\n\n" + |
|
|
|
notes = "Returns the page of notifications for current user." + NEW_LINE + |
|
|
|
PAGE_DATA_PARAMETERS + |
|
|
|
AVAILABLE_FOR_ANY_AUTHORIZED_USER + NEW_LINE + |
|
|
|
"**WebSocket API**:\n\n" + |
|
|
|
"There are 2 types of subscriptions: one for unread notifications count, another for unread notifications themselves.\n\n" + |
|
|
|
"The URI for opening WS session for notifications: `/api/ws/plugins/notifications`.\n\n" + |
|
|
|
"Subscription command for unread notifications count:\n" + |
|
|
|
@ -144,11 +158,17 @@ public class NotificationController extends BaseController { |
|
|
|
"}\n```") |
|
|
|
@GetMapping("/notifications") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
|
|
|
public PageData<Notification> getNotifications(@RequestParam int pageSize, |
|
|
|
public PageData<Notification> getNotifications(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) |
|
|
|
@RequestParam int pageSize, |
|
|
|
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) |
|
|
|
@RequestParam int page, |
|
|
|
@ApiParam(value = "Case-insensitive 'substring' filter based on notification subject or text") |
|
|
|
@RequestParam(required = false) String textSearch, |
|
|
|
@ApiParam(value = SORT_PROPERTY_DESCRIPTION) |
|
|
|
@RequestParam(required = false) String sortProperty, |
|
|
|
@ApiParam(value = SORT_ORDER_DESCRIPTION) |
|
|
|
@RequestParam(required = false) String sortOrder, |
|
|
|
@ApiParam(value = "To search for unread notifications only") |
|
|
|
@RequestParam(defaultValue = "false") boolean unreadOnly, |
|
|
|
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { |
|
|
|
// no permissions
|
|
|
|
@ -156,6 +176,9 @@ public class NotificationController extends BaseController { |
|
|
|
return notificationService.findNotificationsByRecipientIdAndReadStatus(user.getTenantId(), user.getId(), unreadOnly, pageLink); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Mark notification as read (markNotificationAsRead)", |
|
|
|
notes = "Marks notification as read by its id." + |
|
|
|
AVAILABLE_FOR_ANY_AUTHORIZED_USER) |
|
|
|
@PutMapping("/notification/{id}/read") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
|
|
|
public void markNotificationAsRead(@PathVariable UUID id, |
|
|
|
@ -165,6 +188,9 @@ public class NotificationController extends BaseController { |
|
|
|
notificationCenter.markNotificationAsRead(user.getTenantId(), user.getId(), notificationId); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Mark all notifications as read (markAllNotificationsAsRead)", |
|
|
|
notes = "Marks all unread notifications as read." + |
|
|
|
AVAILABLE_FOR_ANY_AUTHORIZED_USER) |
|
|
|
@PutMapping("/notifications/read") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
|
|
|
public void markAllNotificationsAsRead(@AuthenticationPrincipal SecurityUser user) { |
|
|
|
@ -172,6 +198,9 @@ public class NotificationController extends BaseController { |
|
|
|
notificationCenter.markAllNotificationsAsRead(user.getTenantId(), user.getId()); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Delete notification (deleteNotification)", |
|
|
|
notes = "Deletes notification by its id." + |
|
|
|
AVAILABLE_FOR_ANY_AUTHORIZED_USER) |
|
|
|
@DeleteMapping("/notification/{id}") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
|
|
|
public void deleteNotification(@PathVariable UUID id, |
|
|
|
@ -181,6 +210,35 @@ public class NotificationController extends BaseController { |
|
|
|
notificationCenter.deleteNotification(user.getTenantId(), user.getId(), notificationId); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Create notification request (createNotificationRequest)", |
|
|
|
notes = "Processes notification request.\n" + |
|
|
|
"Mandatory request properties are `targets` (list of targets ids to send notification to), " + |
|
|
|
"and either `templateId` (existing notification template id) or `template` (to send notification without saving the template).\n" + |
|
|
|
"Optionally, you can set `sendingDelayInSec` inside the `additionalConfig` field to schedule the notification." + NEW_LINE + |
|
|
|
"For each enabled delivery method in the notification template, there must be a target in the `targets` list that supports this delivery method: " + |
|
|
|
"if you chose `WEB`, `EMAIL` or `SMS` - there must be at least one target in `targets` of `PLATFORM_USERS` type.\n" + |
|
|
|
"For `SLACK` delivery method - you need to chose at least one `SLACK` notification target." + NEW_LINE + |
|
|
|
"Notification request object with `PROCESSING` status will be returned immediately, " + |
|
|
|
"and the notification sending itself is done asynchronously. After all notifications are sent, " + |
|
|
|
"the `status` of the request becomes `SENT`. Use `getNotificationRequestById` to see " + |
|
|
|
"the notification request processing status and some sending stats. " + NEW_LINE + |
|
|
|
"Here is an example of notification request to one target using saved template:\n" + |
|
|
|
MARKDOWN_CODE_BLOCK_START + |
|
|
|
"{\n" + |
|
|
|
" \"templateId\": {\n" + |
|
|
|
" \"entityType\": \"NOTIFICATION_TEMPLATE\",\n" + |
|
|
|
" \"id\": \"6dbc3670-e4dd-11ed-9401-dbcc5dff78be\"\n" + |
|
|
|
" },\n" + |
|
|
|
" \"targets\": [\n" + |
|
|
|
" \"320e3ed0-d785-11ed-a06c-21dd57dd88ca\"\n" + |
|
|
|
" ],\n" + |
|
|
|
" \"additionalConfig\": {\n" + |
|
|
|
" \"sendingDelayInSec\": 0\n" + |
|
|
|
" }\n" + |
|
|
|
"}" + |
|
|
|
MARKDOWN_CODE_BLOCK_END + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH |
|
|
|
) |
|
|
|
@PostMapping("/notification/request") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public NotificationRequest createNotificationRequest(@RequestBody @Valid NotificationRequest notificationRequest, |
|
|
|
@ -200,9 +258,15 @@ public class NotificationController extends BaseController { |
|
|
|
return doSaveAndLog(EntityType.NOTIFICATION_REQUEST, notificationRequest, (tenantId, request) -> notificationCenter.processNotificationRequest(tenantId, request, null)); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Get notification request preview (getNotificationRequestPreview)", |
|
|
|
notes = "Returns preview for notification request." + NEW_LINE + |
|
|
|
"`processedTemplates` shows how the notifications for each delivery method will look like " + |
|
|
|
"for the first recipient of the corresponding notification target." + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@PostMapping("/notification/request/preview") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public NotificationRequestPreview getNotificationRequestPreview(@RequestBody @Valid NotificationRequest request, |
|
|
|
@ApiParam(value = "Amount of the recipients to show in preview") |
|
|
|
@RequestParam(defaultValue = "20") int recipientsPreviewSize, |
|
|
|
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { |
|
|
|
NotificationTemplate template; |
|
|
|
@ -281,6 +345,9 @@ public class NotificationController extends BaseController { |
|
|
|
return preview; |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Get notification request by id (getNotificationRequestById)", |
|
|
|
notes = "Fetches notification request info by request id." + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@GetMapping("/notification/request/{id}") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public NotificationRequestInfo getNotificationRequestById(@PathVariable UUID id) throws ThingsboardException { |
|
|
|
@ -288,12 +355,21 @@ public class NotificationController extends BaseController { |
|
|
|
return checkEntityId(notificationRequestId, notificationRequestService::findNotificationRequestInfoById, Operation.READ); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Get notification requests (getNotificationRequests)", |
|
|
|
notes = "Returns the page of notification requests submitted by users of this tenant or sysadmins." + NEW_LINE + |
|
|
|
PAGE_DATA_PARAMETERS + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@GetMapping("/notification/requests") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public PageData<NotificationRequestInfo> getNotificationRequests(@RequestParam int pageSize, |
|
|
|
public PageData<NotificationRequestInfo> getNotificationRequests(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) |
|
|
|
@RequestParam int pageSize, |
|
|
|
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) |
|
|
|
@RequestParam int page, |
|
|
|
@ApiParam(value = "Case-insensitive 'substring' filed based on the used template name") |
|
|
|
@RequestParam(required = false) String textSearch, |
|
|
|
@ApiParam(value = SORT_PROPERTY_DESCRIPTION) |
|
|
|
@RequestParam(required = false) String sortProperty, |
|
|
|
@ApiParam(value = SORT_ORDER_DESCRIPTION) |
|
|
|
@RequestParam(required = false) String sortOrder, |
|
|
|
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { |
|
|
|
// generic permission
|
|
|
|
@ -301,6 +377,11 @@ public class NotificationController extends BaseController { |
|
|
|
return notificationRequestService.findNotificationRequestsInfosByTenantIdAndOriginatorType(user.getTenantId(), EntityType.USER, pageLink); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Delete notification request (deleteNotificationRequest)", |
|
|
|
notes = "Deletes notification request by its id." + NEW_LINE + |
|
|
|
"If the request has status `SENT` - all sent notifications for this request will be deleted. " + |
|
|
|
"If it is `SCHEDULED`, the request will be cancelled." + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@DeleteMapping("/notification/request/{id}") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public void deleteNotificationRequest(@PathVariable UUID id) throws Exception { |
|
|
|
@ -310,6 +391,21 @@ public class NotificationController extends BaseController { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ApiOperation(value = "Save notification settings (saveNotificationSettings)", |
|
|
|
notes = "Saves notification settings for this tenant or sysadmin.\n" + |
|
|
|
"`deliveryMethodsConfigs` of the settings must be specified." + NEW_LINE + |
|
|
|
"Here is an example of the notification settings with Slack configuration:\n" + |
|
|
|
MARKDOWN_CODE_BLOCK_START + |
|
|
|
"{\n" + |
|
|
|
" \"deliveryMethodsConfigs\": {\n" + |
|
|
|
" \"SLACK\": {\n" + |
|
|
|
" \"method\": \"SLACK\",\n" + |
|
|
|
" \"botToken\": \"xoxb-....\"\n" + |
|
|
|
" }\n" + |
|
|
|
" }\n" + |
|
|
|
"}" + |
|
|
|
MARKDOWN_CODE_BLOCK_END + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@PostMapping("/notification/settings") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public NotificationSettings saveNotificationSettings(@RequestBody @Valid NotificationSettings notificationSettings, |
|
|
|
@ -320,6 +416,9 @@ public class NotificationController extends BaseController { |
|
|
|
return notificationSettings; |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Get notification settings (getNotificationSettings)", |
|
|
|
notes = "Retrieves notification settings for this tenant or sysadmin." + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@GetMapping("/notification/settings") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public NotificationSettings getNotificationSettings(@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { |
|
|
|
@ -328,6 +427,9 @@ public class NotificationController extends BaseController { |
|
|
|
return notificationSettingsService.findNotificationSettings(tenantId); |
|
|
|
} |
|
|
|
|
|
|
|
@ApiOperation(value = "Get available delivery methods (getAvailableDeliveryMethods)", |
|
|
|
notes = "Returns the list of delivery methods that are properly configured and are allowed to be used for sending notifications." + |
|
|
|
SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) |
|
|
|
@GetMapping("/notification/deliveryMethods") |
|
|
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
|
|
|
public Set<NotificationDeliveryMethod> getAvailableDeliveryMethods(@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { |
|
|
|
|