Commit 05d944e5bd727f837fc00c3a4821125b2feda1a8
Merge remote-tracking branch 'origin/lwm2m_controller_swagger'
Showing
4 changed files
with
92 additions
and
8 deletions
@@ -176,6 +176,51 @@ public class ControllerConstants { | @@ -176,6 +176,51 @@ public class ControllerConstants { | ||
176 | protected static final String EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{\n" + | 176 | protected static final String EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{\n" + |
177 | " \"eventType\":\"DEBUG_RULE_CHAIN\",\n" + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END; | 177 | " \"eventType\":\"DEBUG_RULE_CHAIN\",\n" + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END; |
178 | 178 | ||
179 | + protected static final String IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION = "A Boolean value representing the Server SecurityInfo for future Bootstrap client mode settings. Values: 'true' for Bootstrap Server; 'false' for Lwm2m Server. "; | ||
180 | + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION = | ||
181 | + " {\n\"class org.thingsboard.server.common.data.Device\":{\n" + | ||
182 | + " \"id\": \"null\",\n" + | ||
183 | + " \"createdTime\":0,\n" + | ||
184 | + " \"additionalInfo\":\"null\",\n" + | ||
185 | + " \"tenantId\":\"null\",\n" + | ||
186 | + " \"customerId\":\"null\",\n" + | ||
187 | + " \"name\":\"LwRpk00000000\",\n" + | ||
188 | + " \"type\":\"lwm2mProfileRpk\",\n" + | ||
189 | + " \"label\":\"null\",\"" + | ||
190 | + " \"deviceProfileId\":\"null\",\n" + | ||
191 | + " \"deviceData\":\"null\",\n" + | ||
192 | + " \"firmwareId\":\"null\",\n" + | ||
193 | + " \"softwareId\":\"null\"\n" + | ||
194 | + " },\n" + | ||
195 | + " \"class org.thingsboard.server.common.data.security.DeviceCredentials\":{\n" + | ||
196 | + " \"class_DeviceCredentials1\":{\n" + | ||
197 | + " \"id\":\"null\",\n" + | ||
198 | + " \"createdTime\":0,\n" + | ||
199 | + " \"deviceId\":\"null|',\n" + | ||
200 | + " \"credentialsType\":\"LWM2M_CREDENTIALS\",\n" + | ||
201 | + " \"credentialsId\":\"LwRpk00000000\",\n" + | ||
202 | + " \"credentialsValue\":{\n" + | ||
203 | + " \"client\":{\n" + | ||
204 | + " \"endpoint\":\"LwRpk00000000\",\n" + | ||
205 | + " \"securityConfigClientMode\":\"RPK\",\n" + | ||
206 | + " \"key\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\"\n" + | ||
207 | + " },\n" + | ||
208 | + " \"bootstrap\":{\n" + | ||
209 | + " \"bootstrapServer\":{\n" + | ||
210 | + " \"securityMode\":\"RPK\",\n" + | ||
211 | + " \"clientPublicKeyOrId\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\",\n" + | ||
212 | + " \"clientSecretKey\":\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\"" + | ||
213 | + " },\n" + | ||
214 | + " \"lwm2mServer\":{\n" + | ||
215 | + " \"securityMode\":\"RPK\",\n" + | ||
216 | + " \"clientPublicKeyOrId\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\",\n" + | ||
217 | + " \"clientSecretKey\":\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\"\n" + | ||
218 | + " }\n" + | ||
219 | + " }\n" + | ||
220 | + " }\n" + | ||
221 | + " }\n" + | ||
222 | + "}"; | ||
223 | + | ||
179 | protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE + | 224 | protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE + |
180 | "Provides a hint about the data type of the entity field that is defined in the filter key. " + | 225 | "Provides a hint about the data type of the entity field that is defined in the filter key. " + |
181 | "The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values." + | 226 | "The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values." + |
@@ -16,6 +16,8 @@ | @@ -16,6 +16,8 @@ | ||
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | +import io.swagger.annotations.ApiOperation; | ||
20 | +import io.swagger.annotations.ApiParam; | ||
19 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.security.access.prepost.PreAuthorize; | 22 | import org.springframework.security.access.prepost.PreAuthorize; |
21 | import org.springframework.web.bind.annotation.PathVariable; | 23 | import org.springframework.web.bind.annotation.PathVariable; |
@@ -35,16 +37,28 @@ import org.thingsboard.server.service.security.permission.Resource; | @@ -35,16 +37,28 @@ import org.thingsboard.server.service.security.permission.Resource; | ||
35 | 37 | ||
36 | import java.util.Map; | 38 | import java.util.Map; |
37 | 39 | ||
40 | +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION; | ||
41 | +import static org.thingsboard.server.controller.ControllerConstants.IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION; | ||
42 | +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; | ||
43 | + | ||
38 | @Slf4j | 44 | @Slf4j |
39 | @RestController | 45 | @RestController |
40 | @TbCoreComponent | 46 | @TbCoreComponent |
41 | @RequestMapping("/api") | 47 | @RequestMapping("/api") |
42 | public class Lwm2mController extends BaseController { | 48 | public class Lwm2mController extends BaseController { |
49 | + public static final String IS_BOOTSTRAP_SERVER = "isBootstrapServer"; | ||
50 | + | ||
43 | 51 | ||
52 | + @ApiOperation(value = "Get Lwm2m Bootstrap SecurityInfo (getLwm2mBootstrapSecurityInfo)", | ||
53 | + notes = "Get the Lwm2m Bootstrap SecurityInfo object (of the current server) based on the provided isBootstrapServer parameter. If isBootstrapServer == true, get the parameters of the current Bootstrap Server. If isBootstrapServer == false, get the parameters of the current Lwm2m Server. Used for client settings when starting the client in Bootstrap mode. " + | ||
54 | + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, | ||
55 | + produces = "application/json") | ||
44 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 56 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
45 | @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET) | 57 | @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET) |
46 | @ResponseBody | 58 | @ResponseBody |
47 | - public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("isBootstrapServer") boolean bootstrapServer) throws ThingsboardException { | 59 | + public ServerSecurityConfig getLwm2mBootstrapSecurityInfo( |
60 | + @ApiParam(value = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION) | ||
61 | + @PathVariable(IS_BOOTSTRAP_SERVER) boolean bootstrapServer) throws ThingsboardException { | ||
48 | try { | 62 | try { |
49 | return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(bootstrapServer); | 63 | return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(bootstrapServer); |
50 | } catch (Exception e) { | 64 | } catch (Exception e) { |
@@ -52,13 +66,26 @@ public class Lwm2mController extends BaseController { | @@ -52,13 +66,26 @@ public class Lwm2mController extends BaseController { | ||
52 | } | 66 | } |
53 | } | 67 | } |
54 | 68 | ||
69 | + @ApiOperation(value = "Create Device (saveDevice) with credentials ", | ||
70 | + notes = "\nCreate new Device with credentials (example with security mode: RPK\n" + | ||
71 | + "\nRequestBody is the Map<Class<?>, Object>:\n" + | ||
72 | + "\nThe first param of this map: Device\n"+ | ||
73 | + "\n-- key1 = \"class org.thingsboard.server.common.data.Device\" - value1 = \"new Device()\"\n" + | ||
74 | + "\nThe second param of this map: Device credentials\n" + | ||
75 | + "\n-- key2 = \"class org.thingsboard.server.common.data.security.DeviceCredentials\" - value2 = \"new DeviceCredentials()\"\n" + | ||
76 | + "\n- Example of the RequestBody with security mode: RPK:\n" + | ||
77 | + "\n- " + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION + "\n" + | ||
78 | + "\nWhen creating new device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address).\n" + | ||
79 | + "\nAfter creating new device Device DeviceCredentials is added to new Device." | ||
80 | + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) | ||
55 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 81 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
56 | @RequestMapping(value = "/lwm2m/device-credentials", method = RequestMethod.POST) | 82 | @RequestMapping(value = "/lwm2m/device-credentials", method = RequestMethod.POST) |
57 | @ResponseBody | 83 | @ResponseBody |
58 | - public Device saveDeviceWithCredentials(@RequestBody (required=false) Map<Class<?>, Object> deviceWithDeviceCredentials) throws ThingsboardException { | 84 | + public Device saveDeviceWithCredentials(@ApiParam(value = DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION) |
85 | + @RequestBody(required = false) Map<Class<?>, Object> deviceWithDeviceCredentials) throws ThingsboardException { | ||
59 | ObjectMapper mapper = new ObjectMapper(); | 86 | ObjectMapper mapper = new ObjectMapper(); |
60 | Device device = checkNotNull(mapper.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class)); | 87 | Device device = checkNotNull(mapper.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class)); |
61 | - DeviceCredentials credentials = checkNotNull(mapper.convertValue( deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class)); | 88 | + DeviceCredentials credentials = checkNotNull(mapper.convertValue(deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class)); |
62 | try { | 89 | try { |
63 | device.setTenantId(getCurrentUser().getTenantId()); | 90 | device.setTenantId(getCurrentUser().getTenantId()); |
64 | checkEntity(device.getId(), device, Resource.DEVICE); | 91 | checkEntity(device.getId(), device, Resource.DEVICE); |
@@ -15,17 +15,30 @@ | @@ -15,17 +15,30 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data.lwm2m; | 16 | package org.thingsboard.server.common.data.lwm2m; |
17 | 17 | ||
18 | +import io.swagger.annotations.ApiModel; | ||
19 | +import io.swagger.annotations.ApiModelProperty; | ||
18 | import lombok.Data; | 20 | import lombok.Data; |
19 | 21 | ||
22 | +@ApiModel | ||
20 | @Data | 23 | @Data |
21 | public class ServerSecurityConfig { | 24 | public class ServerSecurityConfig { |
25 | + @ApiModelProperty(position = 1, value = "Is Bootstrap Server.", example = "true", readOnly = true) | ||
26 | + boolean bootstrapServerIs = true; | ||
27 | + @ApiModelProperty(position = 2, value = "Host No Security.", example = "0.0.0.0", readOnly = true) | ||
22 | String host; | 28 | String host; |
23 | - String securityHost; | 29 | + @ApiModelProperty(position = 3, value = "Port No Security.", example = "5687", readOnly = true) |
24 | Integer port; | 30 | Integer port; |
31 | + @ApiModelProperty(position = 4, value = "Host Security.", example = "0.0.0.0", readOnly = true) | ||
32 | + String securityHost; | ||
33 | + @ApiModelProperty(position = 5, value = "Port Security.", example = "5688", readOnly = true) | ||
25 | Integer securityPort; | 34 | Integer securityPort; |
26 | - String serverPublicKey; | ||
27 | - boolean bootstrapServerIs = true; | ||
28 | - Integer clientHoldOffTime = 1; | 35 | + @ApiModelProperty(position = 5, value = "Server short Id.", example = "111", readOnly = true) |
29 | Integer serverId = 111; | 36 | Integer serverId = 111; |
37 | + @ApiModelProperty(position = 7, value = "Client Hold Off Time.", example = "1", readOnly = true) | ||
38 | + Integer clientHoldOffTime = 1; | ||
39 | + @ApiModelProperty(position = 8, value = "Server Public Key (formar base64).", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + | ||
40 | + "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", readOnly = true) | ||
41 | + String serverPublicKey; | ||
42 | + @ApiModelProperty(position = 9, value = "Bootstrap Server Account Timeout.", example = "0", readOnly = true) | ||
30 | Integer bootstrapServerAccountTimeout = 0; | 43 | Integer bootstrapServerAccountTimeout = 0; |
31 | } | 44 | } |
@@ -1134,7 +1134,6 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { | @@ -1134,7 +1134,6 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { | ||
1134 | Map<Class<?>, Object> deviceCredentials = new ConcurrentHashMap<>(); | 1134 | Map<Class<?>, Object> deviceCredentials = new ConcurrentHashMap<>(); |
1135 | deviceCredentials.put(Device.class, device); | 1135 | deviceCredentials.put(Device.class, device); |
1136 | deviceCredentials.put(DeviceCredentials.class, credentials); | 1136 | deviceCredentials.put(DeviceCredentials.class, credentials); |
1137 | -// return restTemplate.postForEntity(baseURL + "/api/lwm2m/device-credentials", deviceCredentials, Device.class).getBody(); | ||
1138 | ResponseEntity<Device> deviceOpt = restTemplate.postForEntity(baseURL + "/api/lwm2m/device-credentials", deviceCredentials, Device.class); | 1137 | ResponseEntity<Device> deviceOpt = restTemplate.postForEntity(baseURL + "/api/lwm2m/device-credentials", deviceCredentials, Device.class); |
1139 | return Optional.ofNullable(deviceOpt.getBody()); | 1138 | return Optional.ofNullable(deviceOpt.getBody()); |
1140 | } catch (HttpClientErrorException exception) { | 1139 | } catch (HttpClientErrorException exception) { |