Showing
3 changed files
with
74 additions
and
34 deletions
... | ... | @@ -179,12 +179,14 @@ public abstract class BaseController { |
179 | 179 | public static final String ENTITY_ID_PARAM_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; |
180 | 180 | public static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'"; |
181 | 181 | public static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; |
182 | + public static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; | |
182 | 183 | |
183 | 184 | protected static final String SYSTEM_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' authority."; |
184 | 185 | protected static final String SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' authority."; |
185 | 186 | protected static final String TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' authority."; |
186 | 187 | protected static final String TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority."; |
187 | 188 | protected static final String CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'CUSTOMER_USER' authority."; |
189 | + protected static final String AVAILABLE_FOR_ANY_AUTHORIZED_USER = "\n\nAvailable for any authorized user. "; | |
188 | 190 | |
189 | 191 | protected static final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page"; |
190 | 192 | protected static final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0"; |
... | ... | @@ -195,6 +197,8 @@ public abstract class BaseController { |
195 | 197 | |
196 | 198 | protected static final String ASSET_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the asset name."; |
197 | 199 | protected static final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title."; |
200 | + protected static final String WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the widget bundle title."; | |
201 | + protected static final String WIDGET_TYPE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the widget type title."; | |
198 | 202 | protected static final String RPC_TEXT_SEARCH_DESCRIPTION = "Not implemented. Leave empty."; |
199 | 203 | protected static final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name."; |
200 | 204 | protected static final String USER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the user email."; |
... | ... | @@ -222,6 +226,8 @@ public abstract class BaseController { |
222 | 226 | protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id"; |
223 | 227 | protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; |
224 | 228 | protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root"; |
229 | + protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId"; | |
230 | + protected static final String WIDGET_TYPE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, alias, bundleAlias, name"; | |
225 | 231 | protected static final String AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, entityType, entityName, userName, actionType, actionStatus"; |
226 | 232 | protected static final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)"; |
227 | 233 | protected static final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC"; | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.controller; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiOperation; | |
19 | +import io.swagger.annotations.ApiParam; | |
18 | 20 | import org.springframework.http.HttpStatus; |
19 | 21 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | 22 | import org.springframework.web.bind.annotation.PathVariable; |
... | ... | @@ -44,10 +46,16 @@ import java.util.List; |
44 | 46 | @RequestMapping("/api") |
45 | 47 | public class WidgetsBundleController extends BaseController { |
46 | 48 | |
49 | + private static final String WIDGET_BUNDLE_DESCRIPTION = "Widget Bundle represents a group(bundle) of widgets. Widgets are grouped into bundle by type or use case. "; | |
50 | + | |
51 | + @ApiOperation(value = "Get Widget Bundle (getWidgetsBundleById)", | |
52 | + notes = "Get the Widget Bundle based on the provided Widget Bundle Id. " + WIDGET_BUNDLE_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER) | |
47 | 53 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
48 | 54 | @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.GET) |
49 | 55 | @ResponseBody |
50 | - public WidgetsBundle getWidgetsBundleById(@PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { | |
56 | + public WidgetsBundle getWidgetsBundleById( | |
57 | + @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION) | |
58 | + @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { | |
51 | 59 | checkParameter("widgetsBundleId", strWidgetsBundleId); |
52 | 60 | try { |
53 | 61 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); |
... | ... | @@ -57,10 +65,21 @@ public class WidgetsBundleController extends BaseController { |
57 | 65 | } |
58 | 66 | } |
59 | 67 | |
68 | + @ApiOperation(value = "Create Or Update Widget Bundle (saveWidgetsBundle)", | |
69 | + notes = "Create or update the Widget Bundle. " + WIDGET_BUNDLE_DESCRIPTION + " " + | |
70 | + "When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " + | |
71 | + "The newly created Widget Bundle Id will be present in the response. " + | |
72 | + "Specify existing Widget Bundle id to update the Widget Bundle. " + | |
73 | + "Referencing non-existing Widget Bundle Id will cause 'Not Found' error." + | |
74 | + "\n\nWidget Bundle alias is unique in the scope of tenant. " + | |
75 | + "Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create bundle request is sent by user with 'SYS_ADMIN' authority." | |
76 | + + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) | |
60 | 77 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
61 | 78 | @RequestMapping(value = "/widgetsBundle", method = RequestMethod.POST) |
62 | 79 | @ResponseBody |
63 | - public WidgetsBundle saveWidgetsBundle(@RequestBody WidgetsBundle widgetsBundle) throws ThingsboardException { | |
80 | + public WidgetsBundle saveWidgetsBundle( | |
81 | + @ApiParam(value = "A JSON value representing the Widget Bundle.") | |
82 | + @RequestBody WidgetsBundle widgetsBundle) throws ThingsboardException { | |
64 | 83 | try { |
65 | 84 | if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { |
66 | 85 | widgetsBundle.setTenantId(TenantId.SYS_TENANT_ID); |
... | ... | @@ -80,6 +99,8 @@ public class WidgetsBundleController extends BaseController { |
80 | 99 | } |
81 | 100 | } |
82 | 101 | |
102 | + @ApiOperation(value = "Delete widgets bundle (deleteWidgetsBundle)", | |
103 | + notes = "Deletes the widget bundle. Referencing non-existing Widget Bundle Id will cause an error." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) | |
83 | 104 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") |
84 | 105 | @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.DELETE) |
85 | 106 | @ResponseStatus(value = HttpStatus.OK) |
... | ... | @@ -97,14 +118,22 @@ public class WidgetsBundleController extends BaseController { |
97 | 118 | } |
98 | 119 | } |
99 | 120 | |
121 | + @ApiOperation(value = "Get Widget Bundles (getWidgetsBundles)", | |
122 | + notes = "Returns a page of Widget Bundle objects available for current user. " + WIDGET_BUNDLE_DESCRIPTION + " " + | |
123 | + PAGE_DATA_PARAMETERS + AVAILABLE_FOR_ANY_AUTHORIZED_USER) | |
100 | 124 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
101 | 125 | @RequestMapping(value = "/widgetsBundles", params = {"pageSize", "page"}, method = RequestMethod.GET) |
102 | 126 | @ResponseBody |
103 | 127 | public PageData<WidgetsBundle> getWidgetsBundles( |
128 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
104 | 129 | @RequestParam int pageSize, |
130 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
105 | 131 | @RequestParam int page, |
132 | + @ApiParam(value = WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION) | |
106 | 133 | @RequestParam(required = false) String textSearch, |
134 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES) | |
107 | 135 | @RequestParam(required = false) String sortProperty, |
136 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
108 | 137 | @RequestParam(required = false) String sortOrder) throws ThingsboardException { |
109 | 138 | try { |
110 | 139 | PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
... | ... | @@ -119,6 +148,8 @@ public class WidgetsBundleController extends BaseController { |
119 | 148 | } |
120 | 149 | } |
121 | 150 | |
151 | + @ApiOperation(value = "Get all Widget Bundles (getWidgetsBundles)", | |
152 | + notes = "Returns an array of Widget Bundle objects that are available for current user." + WIDGET_BUNDLE_DESCRIPTION + " " + AVAILABLE_FOR_ANY_AUTHORIZED_USER) | |
122 | 153 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
123 | 154 | @RequestMapping(value = "/widgetsBundles", method = RequestMethod.GET) |
124 | 155 | @ResponseBody | ... | ... |
... | ... | @@ -15,6 +15,10 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.widget; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
20 | +import lombok.Getter; | |
21 | +import lombok.Setter; | |
18 | 22 | import org.thingsboard.server.common.data.HasTenantId; |
19 | 23 | import org.thingsboard.server.common.data.SearchTextBased; |
20 | 24 | import org.thingsboard.server.common.data.id.TenantId; |
... | ... | @@ -23,17 +27,37 @@ import org.thingsboard.server.common.data.validation.NoXss; |
23 | 27 | |
24 | 28 | import java.util.Arrays; |
25 | 29 | |
30 | +@ApiModel | |
26 | 31 | public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements HasTenantId { |
27 | 32 | |
28 | 33 | private static final long serialVersionUID = -7627368878362410489L; |
29 | 34 | |
35 | + @Getter | |
36 | + @Setter | |
37 | + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true) | |
30 | 38 | private TenantId tenantId; |
39 | + | |
31 | 40 | @NoXss |
41 | + @Getter | |
42 | + @Setter | |
43 | + @ApiModelProperty(position = 4, value = "Unique alias that is used in widget types as a reference widget bundle", readOnly = true) | |
32 | 44 | private String alias; |
45 | + | |
33 | 46 | @NoXss |
47 | + @Getter | |
48 | + @Setter | |
49 | + @ApiModelProperty(position = 5, value = "Title used in search and UI", readOnly = true) | |
34 | 50 | private String title; |
51 | + | |
52 | + @Getter | |
53 | + @Setter | |
54 | + @ApiModelProperty(position = 6, value = "Base64 encoded thumbnail", readOnly = true) | |
35 | 55 | private String image; |
56 | + | |
36 | 57 | @NoXss |
58 | + @Getter | |
59 | + @Setter | |
60 | + @ApiModelProperty(position = 7, value = "Description", readOnly = true) | |
37 | 61 | private String description; |
38 | 62 | |
39 | 63 | public WidgetsBundle() { |
... | ... | @@ -53,42 +77,21 @@ public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements H |
53 | 77 | this.description = widgetsBundle.getDescription(); |
54 | 78 | } |
55 | 79 | |
56 | - public TenantId getTenantId() { | |
57 | - return tenantId; | |
58 | - } | |
59 | - | |
60 | - public void setTenantId(TenantId tenantId) { | |
61 | - this.tenantId = tenantId; | |
62 | - } | |
63 | - | |
64 | - public String getAlias() { | |
65 | - return alias; | |
66 | - } | |
67 | - | |
68 | - public void setAlias(String alias) { | |
69 | - this.alias = alias; | |
70 | - } | |
71 | - | |
72 | - public String getTitle() { | |
73 | - return title; | |
74 | - } | |
75 | - | |
76 | - public void setTitle(String title) { | |
77 | - this.title = title; | |
78 | - } | |
79 | - | |
80 | - public String getImage() { | |
81 | - return image; | |
80 | + @ApiModelProperty(position = 1, value = "JSON object with the Widget Bundle Id. " + | |
81 | + "Specify this field to update the Widget Bundle. " + | |
82 | + "Referencing non-existing Widget Bundle Id will cause error. " + | |
83 | + "Omit this field to create new Widget Bundle." ) | |
84 | + @Override | |
85 | + public WidgetsBundleId getId() { | |
86 | + return super.getId(); | |
82 | 87 | } |
83 | 88 | |
84 | - public void setImage(String image) { | |
85 | - this.image = image; | |
89 | + @ApiModelProperty(position = 2, value = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", readOnly = true) | |
90 | + @Override | |
91 | + public long getCreatedTime() { | |
92 | + return super.getCreatedTime(); | |
86 | 93 | } |
87 | 94 | |
88 | - public String getDescription() { return description; } | |
89 | - | |
90 | - public void setDescription(String description) { this.description = description; } | |
91 | - | |
92 | 95 | @Override |
93 | 96 | public String getSearchText() { |
94 | 97 | return getTitle(); | ... | ... |