Commit 78e00265ec0295c3a8da1d69fe07a982061f086b

Authored by Igor Kulikov
2 parents 362ccf9f 49394fab

Merge branch 'master' of github.com:thingsboard/thingsboard

... ... @@ -25,7 +25,6 @@ import org.springframework.http.ResponseEntity;
25 25 import org.springframework.util.StringUtils;
26 26 import org.springframework.web.context.request.async.DeferredResult;
27 27 import org.thingsboard.common.util.JacksonUtil;
28   -import org.thingsboard.server.common.data.rpc.RpcError;
29 28 import org.thingsboard.server.common.data.DataConstants;
30 29 import org.thingsboard.server.common.data.audit.ActionType;
31 30 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
... ... @@ -34,10 +33,11 @@ import org.thingsboard.server.common.data.id.DeviceId;
34 33 import org.thingsboard.server.common.data.id.EntityId;
35 34 import org.thingsboard.server.common.data.id.TenantId;
36 35 import org.thingsboard.server.common.data.id.UUIDBased;
  36 +import org.thingsboard.server.common.data.rpc.RpcError;
37 37 import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
  38 +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
38 39 import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
39 40 import org.thingsboard.server.queue.util.TbCoreComponent;
40   -import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
41 41 import org.thingsboard.server.service.rpc.LocalRequestMetaData;
42 42 import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
43 43 import org.thingsboard.server.service.security.AccessValidator;
... ...
... ... @@ -15,8 +15,6 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
18   -import com.fasterxml.jackson.databind.JsonNode;
19   -import com.fasterxml.jackson.databind.ObjectMapper;
20 18 import com.fasterxml.jackson.databind.node.ObjectNode;
21 19 import io.swagger.annotations.ApiOperation;
22 20 import io.swagger.annotations.ApiParam;
... ... @@ -50,13 +48,13 @@ import org.thingsboard.server.common.data.security.model.SecuritySettings;
50 48 import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
51 49 import org.thingsboard.server.dao.audit.AuditLogService;
52 50 import org.thingsboard.server.queue.util.TbCoreComponent;
  51 +import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
  52 +import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
53 53 import org.thingsboard.server.service.security.model.ActivateUserRequest;
54 54 import org.thingsboard.server.service.security.model.ChangePasswordRequest;
  55 +import org.thingsboard.server.service.security.model.JwtTokenPair;
55 56 import org.thingsboard.server.service.security.model.ResetPasswordEmailRequest;
56 57 import org.thingsboard.server.service.security.model.ResetPasswordRequest;
57   -import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
58   -import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
59   -import org.thingsboard.server.service.security.model.JwtTokenPair;
60 58 import org.thingsboard.server.service.security.model.SecurityUser;
61 59 import org.thingsboard.server.service.security.model.UserPrincipal;
62 60 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
... ...
... ... @@ -15,7 +15,6 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
18   -import com.fasterxml.jackson.databind.ObjectMapper;
19 18 import com.google.common.util.concurrent.FutureCallback;
20 19 import com.google.common.util.concurrent.Futures;
21 20 import com.google.common.util.concurrent.ListenableFuture;
... ... @@ -85,7 +84,6 @@ import javax.annotation.Nullable;
85 84 import java.io.IOException;
86 85 import java.util.ArrayList;
87 86 import java.util.List;
88   -import java.util.Map;
89 87 import java.util.UUID;
90 88 import java.util.stream.Collectors;
91 89
... ... @@ -99,7 +97,6 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFI
99 97 import static org.thingsboard.server.controller.ControllerConstants.DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES;
100 98 import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TEXT_SEARCH_DESCRIPTION;
101 99 import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_DESCRIPTION;
102   -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION;
103 100 import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN;
104 101 import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
105 102 import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
... ...
... ... @@ -75,11 +75,28 @@ import java.util.concurrent.ExecutionException;
75 75 import java.util.stream.Collectors;
76 76
77 77 import static org.apache.commons.lang3.StringUtils.isBlank;
78   -import static org.thingsboard.server.controller.ControllerConstants.*;
  78 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
  79 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
79 80 import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
80 81 import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
81 82 import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
82 83 import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
  84 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_DESCRIPTION;
  85 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_ID_PARAM_DESCRIPTION;
  86 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_DESCRIPTION;
  87 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES;
  88 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES;
  89 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION;
  90 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TYPE;
  91 +import static org.thingsboard.server.controller.ControllerConstants.MODEL_DESCRIPTION;
  92 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  93 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  94 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  95 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  96 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  97 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  98 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  99 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
83 100 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
84 101
85 102 /**
... ...
... ... @@ -28,18 +28,14 @@ import org.springframework.web.bind.annotation.RequestMethod;
28 28 import org.springframework.web.bind.annotation.ResponseBody;
29 29 import org.springframework.web.bind.annotation.RestController;
30 30 import org.thingsboard.server.common.data.Device;
31   -import org.thingsboard.server.common.data.EntityType;
32 31 import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
33   -import org.thingsboard.server.common.data.audit.ActionType;
34 32 import org.thingsboard.server.common.data.exception.ThingsboardException;
35 33 import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
36 34 import org.thingsboard.server.common.data.security.DeviceCredentials;
37 35 import org.thingsboard.server.queue.util.TbCoreComponent;
38   -import org.thingsboard.server.service.security.permission.Resource;
39 36
40 37 import java.util.Map;
41 38
42   -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION;
43 39 import static org.thingsboard.server.controller.ControllerConstants.IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION;
44 40 import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
45 41
... ...
... ... @@ -52,8 +52,22 @@ import javax.annotation.Nullable;
52 52 import java.util.UUID;
53 53
54 54 import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED;
55   -
56   -import static org.thingsboard.server.controller.ControllerConstants.*;
  55 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID;
  56 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END;
  58 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_START;
  59 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  60 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  61 +import static org.thingsboard.server.controller.ControllerConstants.RPC_ID;
  62 +import static org.thingsboard.server.controller.ControllerConstants.RPC_ID_PARAM_DESCRIPTION;
  63 +import static org.thingsboard.server.controller.ControllerConstants.RPC_SORT_PROPERTY_ALLOWABLE_VALUES;
  64 +import static org.thingsboard.server.controller.ControllerConstants.RPC_STATUS_ALLOWABLE_VALUES;
  65 +import static org.thingsboard.server.controller.ControllerConstants.RPC_TEXT_SEARCH_DESCRIPTION;
  66 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  67 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  68 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  69 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  70 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
57 71
58 72 @RestController
59 73 @TbCoreComponent
... ...
... ... @@ -40,7 +40,19 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
40 40 import org.thingsboard.server.service.security.permission.Operation;
41 41 import org.thingsboard.server.service.security.permission.Resource;
42 42
43   -import static org.thingsboard.server.controller.ControllerConstants.*;
  43 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END;
  44 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_START;
  45 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  46 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  48 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  49 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  51 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  52 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_ID_PARAM_DESCRIPTION;
  53 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES;
  54 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES;
  55 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION;
44 56
45 57 @RestController
46 58 @TbCoreComponent
... ...
... ... @@ -62,7 +62,25 @@ import org.thingsboard.server.service.security.system.SystemSecurityService;
62 62 import javax.servlet.http.HttpServletRequest;
63 63 import java.util.List;
64 64
65   -import static org.thingsboard.server.controller.ControllerConstants.*;
  65 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
  66 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  67 +import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_DASHBOARD;
  68 +import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD;
  69 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  70 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  71 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  72 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  73 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  74 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  75 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  76 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  77 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  78 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID;
  79 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION;
  80 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  81 +import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION;
  82 +import static org.thingsboard.server.controller.ControllerConstants.USER_SORT_PROPERTY_ALLOWABLE_VALUES;
  83 +import static org.thingsboard.server.controller.ControllerConstants.USER_TEXT_SEARCH_DESCRIPTION;
66 84
67 85 @RequiredArgsConstructor
68 86 @RestController
... ...
... ... @@ -43,7 +43,9 @@ import org.thingsboard.server.service.security.permission.Resource;
43 43
44 44 import java.util.List;
45 45
46   -import static org.thingsboard.server.controller.ControllerConstants.*;
  46 +import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER;
  47 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  48 +import static org.thingsboard.server.controller.ControllerConstants.WIDGET_TYPE_ID_PARAM_DESCRIPTION;
47 49
48 50 @Slf4j
49 51 @RestController
... ...
... ... @@ -41,7 +41,17 @@ import org.thingsboard.server.service.security.permission.Resource;
41 41
42 42 import java.util.List;
43 43
44   -import static org.thingsboard.server.controller.ControllerConstants.*;
  44 +import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER;
  45 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  46 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  48 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  49 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  51 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  52 +import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_ID_PARAM_DESCRIPTION;
  53 +import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES;
  54 +import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION;
45 55
46 56 @RestController
47 57 @TbCoreComponent
... ...
... ... @@ -17,6 +17,8 @@ package org.thingsboard.server.transport.http;
17 17
18 18 import com.google.gson.JsonObject;
19 19 import com.google.gson.JsonParser;
  20 +import io.swagger.annotations.ApiOperation;
  21 +import io.swagger.annotations.ApiParam;
20 22 import lombok.RequiredArgsConstructor;
21 23 import lombok.extern.slf4j.Slf4j;
22 24 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -68,6 +70,7 @@ import java.util.List;
68 70 import java.util.UUID;
69 71 import java.util.function.Consumer;
70 72
  73 +
71 74 /**
72 75 * @author Andrew Shvayka
73 76 */
... ... @@ -77,14 +80,70 @@ import java.util.function.Consumer;
77 80 @Slf4j
78 81 public class DeviceApiController implements TbTransportService {
79 82
  83 + private static final String MARKDOWN_CODE_BLOCK_START = "\n\n```json\n";
  84 + private static final String MARKDOWN_CODE_BLOCK_END = "\n```\n\n";
  85 +
  86 + private static final String REQUIRE_ACCESS_TOKEN = "The API call is designed to be used by device firmware and requires device access token ('deviceToken'). " +
  87 + "It is not recommended to use this API call by third-party scripts, rule-engine or platform widgets (use 'Telemetry Controller' instead).\n";
  88 +
  89 + private static final String ATTRIBUTE_PAYLOAD_EXAMPLE = "{\n" +
  90 + " \"stringKey\":\"value1\", \n" +
  91 + " \"booleanKey\":true, \n" +
  92 + " \"doubleKey\":42.0, \n" +
  93 + " \"longKey\":73, \n" +
  94 + " \"jsonKey\": {\n" +
  95 + " \"someNumber\": 42,\n" +
  96 + " \"someArray\": [1,2,3],\n" +
  97 + " \"someNestedObject\": {\"key\": \"value\"}\n" +
  98 + " }\n" +
  99 + "}";
  100 +
  101 + protected static final String TS_PAYLOAD = "The request payload is a JSON document with three possible formats:\n\n" +
  102 + "Simple format without timestamp. In such a case, current server time will be used: \n\n" +
  103 + MARKDOWN_CODE_BLOCK_START +
  104 + "{\n" +
  105 + " \"stringKey\":\"value1\", \n" +
  106 + " \"booleanKey\":true, \n" +
  107 + " \"doubleKey\":42.0, \n" +
  108 + " \"longKey\":73, \n" +
  109 + " \"jsonKey\": {\n" +
  110 + " \"someNumber\": 42,\n" +
  111 + " \"someArray\": [1,2,3],\n" +
  112 + " \"someNestedObject\": {\"key\": \"value\"}\n" +
  113 + " }\n" +
  114 + "}" +
  115 + MARKDOWN_CODE_BLOCK_END +
  116 + "\n\n Single JSON object with timestamp: \n\n" +
  117 + MARKDOWN_CODE_BLOCK_START +
  118 + "{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}" +
  119 + MARKDOWN_CODE_BLOCK_END +
  120 + "\n\n JSON array with timestamps: \n\n" +
  121 + MARKDOWN_CODE_BLOCK_START +
  122 + "[\n{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, \n{\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}\n]" +
  123 + MARKDOWN_CODE_BLOCK_END;
  124 +
  125 + private static final String ACCESS_TOKEN_PARAM_DESCRIPTION = "Your device access token.";
  126 +
80 127 @Autowired
81 128 private HttpTransportContext transportContext;
82 129
  130 + @ApiOperation(value = "Get attributes (getDeviceAttributes)",
  131 + notes = "Returns all attributes that belong to device. "
  132 + + "Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. "
  133 + + "\n Example of the result: "
  134 + + MARKDOWN_CODE_BLOCK_START
  135 + + ATTRIBUTE_PAYLOAD_EXAMPLE
  136 + + MARKDOWN_CODE_BLOCK_END
  137 + + REQUIRE_ACCESS_TOKEN,
  138 + produces = MediaType.APPLICATION_JSON_VALUE)
83 139 @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json")
84   - public DeferredResult<ResponseEntity> getDeviceAttributes(@PathVariable("deviceToken") String deviceToken,
85   - @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
86   - @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys,
87   - HttpServletRequest httpRequest) {
  140 + public DeferredResult<ResponseEntity> getDeviceAttributes(
  141 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  142 + @PathVariable("deviceToken") String deviceToken,
  143 + @ApiParam(value = "Comma separated key names for attribute with client scope", required = true, defaultValue = "state")
  144 + @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
  145 + @ApiParam(value = "Comma separated key names for attribute with shared scope", required = true, defaultValue = "configuration")
  146 + @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) {
88 147 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
89 148 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
90 149 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -106,9 +165,20 @@ public class DeviceApiController implements TbTransportService {
106 165 return responseWriter;
107 166 }
108 167
  168 + @ApiOperation(value = "Post attributes (postDeviceAttributes)",
  169 + notes = "Post client attribute updates on behalf of device. "
  170 + + "\n Example of the request: "
  171 + + MARKDOWN_CODE_BLOCK_START
  172 + + ATTRIBUTE_PAYLOAD_EXAMPLE
  173 + + MARKDOWN_CODE_BLOCK_END
  174 + + REQUIRE_ACCESS_TOKEN,
  175 + produces = MediaType.APPLICATION_JSON_VALUE)
109 176 @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.POST)
110   - public DeferredResult<ResponseEntity> postDeviceAttributes(@PathVariable("deviceToken") String deviceToken,
111   - @RequestBody String json, HttpServletRequest request) {
  177 + public DeferredResult<ResponseEntity> postDeviceAttributes(
  178 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  179 + @PathVariable("deviceToken") String deviceToken,
  180 + @ApiParam(value = "JSON with attribute key-value pairs. See API call description for example.")
  181 + @RequestBody String json) {
112 182 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
113 183 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
114 184 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -119,9 +189,17 @@ public class DeviceApiController implements TbTransportService {
119 189 return responseWriter;
120 190 }
121 191
  192 + @ApiOperation(value = "Post time-series data (postTelemetry)",
  193 + notes = "Post time-series data on behalf of device. "
  194 + + "\n Example of the request: "
  195 + + TS_PAYLOAD
  196 + + REQUIRE_ACCESS_TOKEN,
  197 + produces = MediaType.APPLICATION_JSON_VALUE)
122 198 @RequestMapping(value = "/{deviceToken}/telemetry", method = RequestMethod.POST)
123   - public DeferredResult<ResponseEntity> postTelemetry(@PathVariable("deviceToken") String deviceToken,
124   - @RequestBody String json, HttpServletRequest request) {
  199 + public DeferredResult<ResponseEntity> postTelemetry(
  200 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  201 + @PathVariable("deviceToken") String deviceToken,
  202 + @RequestBody String json, HttpServletRequest request) {
125 203 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
126 204 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
127 205 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -132,9 +210,22 @@ public class DeviceApiController implements TbTransportService {
132 210 return responseWriter;
133 211 }
134 212
  213 + @ApiOperation(value = "Save claiming information (claimDevice)",
  214 + notes = "Saves the information required for user to claim the device. " +
  215 + "See more info about claiming in the corresponding 'Claiming devices' platform documentation."
  216 + + "\n Example of the request payload: "
  217 + + MARKDOWN_CODE_BLOCK_START
  218 + + "{\"secretKey\":\"value\", \"durationMs\":60000}"
  219 + + MARKDOWN_CODE_BLOCK_END
  220 + + "Note: both 'secretKey' and 'durationMs' is optional parameters. " +
  221 + "In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used.\n\n"
  222 + + REQUIRE_ACCESS_TOKEN,
  223 + produces = MediaType.APPLICATION_JSON_VALUE)
135 224 @RequestMapping(value = "/{deviceToken}/claim", method = RequestMethod.POST)
136   - public DeferredResult<ResponseEntity> claimDevice(@PathVariable("deviceToken") String deviceToken,
137   - @RequestBody(required = false) String json, HttpServletRequest request) {
  225 + public DeferredResult<ResponseEntity> claimDevice(
  226 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  227 + @PathVariable("deviceToken") String deviceToken,
  228 + @RequestBody(required = false) String json) {
138 229 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
139 230 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
140 231 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -146,10 +237,18 @@ public class DeviceApiController implements TbTransportService {
146 237 return responseWriter;
147 238 }
148 239
  240 + @ApiOperation(value = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)",
  241 + notes = "Subscribes to RPC commands using http long polling. " +
  242 + "Deprecated, since long polling is resource and network consuming. " +
  243 + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" +
  244 + REQUIRE_ACCESS_TOKEN,
  245 + produces = MediaType.APPLICATION_JSON_VALUE)
149 246 @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = "application/json")
150   - public DeferredResult<ResponseEntity> subscribeToCommands(@PathVariable("deviceToken") String deviceToken,
151   - @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout,
152   - HttpServletRequest httpRequest) {
  247 + public DeferredResult<ResponseEntity> subscribeToCommands(
  248 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  249 + @PathVariable("deviceToken") String deviceToken,
  250 + @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.")
  251 + @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) {
153 252 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
154 253 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
155 254 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -164,10 +263,18 @@ public class DeviceApiController implements TbTransportService {
164 263 return responseWriter;
165 264 }
166 265
  266 + @ApiOperation(value = "Reply to RPC commands (replyToCommand)",
  267 + notes = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" +
  268 + REQUIRE_ACCESS_TOKEN,
  269 + produces = MediaType.APPLICATION_JSON_VALUE)
167 270 @RequestMapping(value = "/{deviceToken}/rpc/{requestId}", method = RequestMethod.POST)
168   - public DeferredResult<ResponseEntity> replyToCommand(@PathVariable("deviceToken") String deviceToken,
169   - @PathVariable("requestId") Integer requestId,
170   - @RequestBody String json, HttpServletRequest request) {
  271 + public DeferredResult<ResponseEntity> replyToCommand(
  272 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  273 + @PathVariable("deviceToken") String deviceToken,
  274 + @ApiParam(value = "RPC request id from the incoming RPC request", required = true, defaultValue = "123")
  275 + @PathVariable("requestId") Integer requestId,
  276 + @ApiParam(value = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true)
  277 + @RequestBody String json) {
171 278 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
172 279 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
173 280 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -177,9 +284,23 @@ public class DeviceApiController implements TbTransportService {
177 284 return responseWriter;
178 285 }
179 286
  287 + @ApiOperation(value = "Send the RPC command (postRpcRequest)",
  288 + notes = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" +
  289 + MARKDOWN_CODE_BLOCK_START +
  290 + "{\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}}" +
  291 + MARKDOWN_CODE_BLOCK_END +
  292 + "The response contains arbitrary JSON with the RPC reply. For example: " +
  293 + MARKDOWN_CODE_BLOCK_START +
  294 + "{\"result\": 4}" +
  295 + MARKDOWN_CODE_BLOCK_END +
  296 + REQUIRE_ACCESS_TOKEN,
  297 + produces = MediaType.APPLICATION_JSON_VALUE)
180 298 @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.POST)
181   - public DeferredResult<ResponseEntity> postRpcRequest(@PathVariable("deviceToken") String deviceToken,
182   - @RequestBody String json, HttpServletRequest httpRequest) {
  299 + public DeferredResult<ResponseEntity> postRpcRequest(
  300 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  301 + @PathVariable("deviceToken") String deviceToken,
  302 + @ApiParam(value = "The RPC request JSON", required = true)
  303 + @RequestBody String json) {
183 304 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<ResponseEntity>();
184 305 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
185 306 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -196,10 +317,18 @@ public class DeviceApiController implements TbTransportService {
196 317 return responseWriter;
197 318 }
198 319
  320 + @ApiOperation(value = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)",
  321 + notes = "Subscribes to client and shared scope attribute updates using http long polling. " +
  322 + "Deprecated, since long polling is resource and network consuming. " +
  323 + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" +
  324 + REQUIRE_ACCESS_TOKEN,
  325 + produces = MediaType.APPLICATION_JSON_VALUE)
199 326 @RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = "application/json")
200   - public DeferredResult<ResponseEntity> subscribeToAttributes(@PathVariable("deviceToken") String deviceToken,
201   - @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout,
202   - HttpServletRequest httpRequest) {
  327 + public DeferredResult<ResponseEntity> subscribeToAttributes(
  328 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  329 + @PathVariable("deviceToken") String deviceToken,
  330 + @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.")
  331 + @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) {
203 332 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
204 333 transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
205 334 new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
... ... @@ -214,26 +343,85 @@ public class DeviceApiController implements TbTransportService {
214 343 return responseWriter;
215 344 }
216 345
  346 + @ApiOperation(value = "Get Device Firmware (getFirmware)",
  347 + notes = "Downloads the current firmware package." +
  348 + "When the platform initiates firmware update, " +
  349 + "it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes." +
  350 + "The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check " +
  351 + "that the firmware that device is downloading matches the firmware it expects to download. " +
  352 + "This is important, since the administrator may change the firmware assignment while device is downloading the firmware. \n\n" +
  353 + "Optional 'chunk' and 'size' parameters may be used to download the firmware in chunks. " +
  354 + "For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. " +
  355 + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" +
  356 + REQUIRE_ACCESS_TOKEN,
  357 + produces = MediaType.APPLICATION_JSON_VALUE)
217 358 @RequestMapping(value = "/{deviceToken}/firmware", method = RequestMethod.GET)
218   - public DeferredResult<ResponseEntity> getFirmware(@PathVariable("deviceToken") String deviceToken,
219   - @RequestParam(value = "title") String title,
220   - @RequestParam(value = "version") String version,
221   - @RequestParam(value = "size", required = false, defaultValue = "0") int size,
222   - @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
  359 + public DeferredResult<ResponseEntity> getFirmware(
  360 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  361 + @PathVariable("deviceToken") String deviceToken,
  362 + @ApiParam(value = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true)
  363 + @RequestParam(value = "title") String title,
  364 + @ApiParam(value = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true)
  365 + @RequestParam(value = "version") String version,
  366 + @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without chunks.")
  367 + @RequestParam(value = "size", required = false, defaultValue = "0") int size,
  368 + @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without chunks.")
  369 + @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
223 370 return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE);
224 371 }
225 372
  373 + @ApiOperation(value = "Get Device Software (getSoftware)",
  374 + notes = "Downloads the current software package." +
  375 + "When the platform initiates software update, " +
  376 + "it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes." +
  377 + "The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check " +
  378 + "that the software that device is downloading matches the software it expects to download. " +
  379 + "This is important, since the administrator may change the software assignment while device is downloading the software. \n\n" +
  380 + "Optional 'chunk' and 'size' parameters may be used to download the software in chunks. " +
  381 + "For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. " +
  382 + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" +
  383 + REQUIRE_ACCESS_TOKEN,
  384 + produces = MediaType.APPLICATION_JSON_VALUE)
226 385 @RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET)
227   - public DeferredResult<ResponseEntity> getSoftware(@PathVariable("deviceToken") String deviceToken,
228   - @RequestParam(value = "title") String title,
229   - @RequestParam(value = "version") String version,
230   - @RequestParam(value = "size", required = false, defaultValue = "0") int size,
231   - @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
  386 + public DeferredResult<ResponseEntity> getSoftware(
  387 + @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")
  388 + @PathVariable("deviceToken") String deviceToken,
  389 + @ApiParam(value = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true)
  390 + @RequestParam(value = "title") String title,
  391 + @ApiParam(value = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true)
  392 + @RequestParam(value = "version") String version,
  393 + @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without using chunks.")
  394 + @RequestParam(value = "size", required = false, defaultValue = "0") int size,
  395 + @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without using chunks.")
  396 + @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
232 397 return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE);
233 398 }
234 399
  400 + @ApiOperation(value = "Provision new device (provisionDevice)",
  401 + notes = "Exchange the provision request to the device credentials. " +
  402 + "See more info about provisioning in the corresponding 'Device provisioning' platform documentation." +
  403 + "Requires valid JSON request with the following format: " +
  404 + MARKDOWN_CODE_BLOCK_START +
  405 + "{\n" +
  406 + " \"deviceName\": \"NEW_DEVICE_NAME\",\n" +
  407 + " \"provisionDeviceKey\": \"u7piawkboq8v32dmcmpp\",\n" +
  408 + " \"provisionDeviceSecret\": \"jpmwdn8ptlswmf4m29bw\"\n" +
  409 + "}" +
  410 + MARKDOWN_CODE_BLOCK_END +
  411 + "Where 'deviceName' is the name of enw or existing device which depends on the provisioning strategy. " +
  412 + "The 'provisionDeviceKey' and 'provisionDeviceSecret' matches info configured in one of the existing device profiles. " +
  413 + "The result of the successful call is the JSON object that contains new credentials:" +
  414 + MARKDOWN_CODE_BLOCK_START + "{\n" +
  415 + " \"credentialsType\":\"ACCESS_TOKEN\",\n" +
  416 + " \"credentialsValue\":\"DEVICE_ACCESS_TOKEN\",\n" +
  417 + " \"status\":\"SUCCESS\"\n" +
  418 + "}" + MARKDOWN_CODE_BLOCK_END
  419 + ,
  420 + produces = MediaType.APPLICATION_JSON_VALUE)
235 421 @RequestMapping(value = "/provision", method = RequestMethod.POST)
236   - public DeferredResult<ResponseEntity> provisionDevice(@RequestBody String json, HttpServletRequest httpRequest) {
  422 + public DeferredResult<ResponseEntity> provisionDevice(
  423 + @ApiParam(value = "JSON with provision request. See API call description for example.")
  424 + @RequestBody String json) {
237 425 DeferredResult<ResponseEntity> responseWriter = new DeferredResult<>();
238 426 transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json),
239 427 new DeviceProvisionCallback(responseWriter));
... ...