Commit 65ad86bedb3713d896707edb86a83dfaf1bad51d
1 parent
940c81b0
RPC v2 to switch from 409 to 504 error code
Showing
14 changed files
with
175 additions
and
108 deletions
application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
renamed from
application/src/main/java/org/thingsboard/server/controller/RpcController.java
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | 9 | * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
... | ... | @@ -16,7 +16,6 @@ |
16 | 16 | package org.thingsboard.server.controller; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | |
20 | 19 | import com.google.common.util.concurrent.FutureCallback; |
21 | 20 | import lombok.extern.slf4j.Slf4j; |
22 | 21 | import org.springframework.beans.factory.annotation.Autowired; |
... | ... | @@ -26,13 +25,12 @@ import org.springframework.http.ResponseEntity; |
26 | 25 | import org.springframework.security.access.prepost.PreAuthorize; |
27 | 26 | import org.springframework.util.StringUtils; |
28 | 27 | import org.springframework.web.bind.annotation.PathVariable; |
29 | -import org.springframework.web.bind.annotation.RequestBody; | |
30 | 28 | import org.springframework.web.bind.annotation.RequestMapping; |
31 | 29 | import org.springframework.web.bind.annotation.RequestMethod; |
32 | 30 | import org.springframework.web.bind.annotation.RequestParam; |
33 | 31 | import org.springframework.web.bind.annotation.ResponseBody; |
34 | -import org.springframework.web.bind.annotation.RestController; | |
35 | 32 | import org.springframework.web.context.request.async.DeferredResult; |
33 | +import org.thingsboard.common.util.JacksonUtil; | |
36 | 34 | import org.thingsboard.rule.engine.api.RpcError; |
37 | 35 | import org.thingsboard.server.common.data.DataConstants; |
38 | 36 | import org.thingsboard.server.common.data.audit.ActionType; |
... | ... | @@ -59,20 +57,15 @@ import org.thingsboard.server.service.security.permission.Operation; |
59 | 57 | import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity; |
60 | 58 | |
61 | 59 | import javax.annotation.Nullable; |
62 | -import java.io.IOException; | |
63 | 60 | import java.util.Optional; |
64 | 61 | import java.util.UUID; |
65 | 62 | |
66 | 63 | /** |
67 | 64 | * Created by ashvayka on 22.03.18. |
68 | 65 | */ |
69 | -@RestController | |
70 | 66 | @TbCoreComponent |
71 | -@RequestMapping(TbUrlConstants.RPC_URL_PREFIX) | |
72 | 67 | @Slf4j |
73 | -public class RpcController extends BaseController { | |
74 | - | |
75 | - protected final ObjectMapper jsonMapper = new ObjectMapper(); | |
68 | +public abstract class AbstractRpcController extends BaseController { | |
76 | 69 | |
77 | 70 | @Autowired |
78 | 71 | private TbCoreDeviceRpcService deviceRpcService; |
... | ... | @@ -81,75 +74,15 @@ public class RpcController extends BaseController { |
81 | 74 | private AccessValidator accessValidator; |
82 | 75 | |
83 | 76 | @Value("${server.rest.server_side_rpc.min_timeout:5000}") |
84 | - private long minTimeout; | |
77 | + protected long minTimeout; | |
85 | 78 | |
86 | 79 | @Value("${server.rest.server_side_rpc.default_timeout:10000}") |
87 | - private long defaultTimeout; | |
88 | - | |
89 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
90 | - @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) | |
91 | - @ResponseBody | |
92 | - public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
93 | - return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); | |
94 | - } | |
95 | - | |
96 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
97 | - @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) | |
98 | - @ResponseBody | |
99 | - public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
100 | - return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); | |
101 | - } | |
102 | - | |
103 | - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
104 | - @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) | |
105 | - @ResponseBody | |
106 | - public Rpc getPersistedRpc(@PathVariable("rpcId") String strRpc) throws ThingsboardException { | |
107 | - checkParameter("RpcId", strRpc); | |
108 | - try { | |
109 | - RpcId rpcId = new RpcId(UUID.fromString(strRpc)); | |
110 | - return checkRpcId(rpcId, Operation.READ); | |
111 | - } catch (Exception e) { | |
112 | - throw handleException(e); | |
113 | - } | |
114 | - } | |
115 | - | |
116 | - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
117 | - @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) | |
118 | - @ResponseBody | |
119 | - public PageData<Rpc> getPersistedRpcByDevice(@PathVariable("deviceId") String strDeviceId, | |
120 | - @RequestParam int pageSize, | |
121 | - @RequestParam int page, | |
122 | - @RequestParam RpcStatus rpcStatus, | |
123 | - @RequestParam(required = false) String textSearch, | |
124 | - @RequestParam(required = false) String sortProperty, | |
125 | - @RequestParam(required = false) String sortOrder) throws ThingsboardException { | |
126 | - checkParameter("DeviceId", strDeviceId); | |
127 | - try { | |
128 | - TenantId tenantId = getCurrentUser().getTenantId(); | |
129 | - PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); | |
130 | - DeviceId deviceId = new DeviceId(UUID.fromString(strDeviceId)); | |
131 | - return checkNotNull(rpcService.findAllByDeviceIdAndStatus(tenantId, deviceId, rpcStatus, pageLink)); | |
132 | - } catch (Exception e) { | |
133 | - throw handleException(e); | |
134 | - } | |
135 | - } | |
136 | - | |
137 | - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") | |
138 | - @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) | |
139 | - @ResponseBody | |
140 | - public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { | |
141 | - checkParameter("RpcId", strRpc); | |
142 | - try { | |
143 | - rpcService.deleteRpc(getTenantId(), new RpcId(UUID.fromString(strRpc))); | |
144 | - } catch (Exception e) { | |
145 | - throw handleException(e); | |
146 | - } | |
147 | - } | |
80 | + protected long defaultTimeout; | |
148 | 81 | |
149 | - private DeferredResult<ResponseEntity> handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody) throws ThingsboardException { | |
82 | + protected DeferredResult<ResponseEntity> handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody, HttpStatus timeoutStatus) throws ThingsboardException { | |
150 | 83 | try { |
151 | - JsonNode rpcRequestBody = jsonMapper.readTree(requestBody); | |
152 | - ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), jsonMapper.writeValueAsString(rpcRequestBody.get("params"))); | |
84 | + JsonNode rpcRequestBody = JacksonUtil.toJsonNode(requestBody); | |
85 | + ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), JacksonUtil.toString(rpcRequestBody.get("params"))); | |
153 | 86 | SecurityUser currentUser = getCurrentUser(); |
154 | 87 | TenantId tenantId = currentUser.getTenantId(); |
155 | 88 | final DeferredResult<ResponseEntity> response = new DeferredResult<>(); |
... | ... | @@ -157,7 +90,7 @@ public class RpcController extends BaseController { |
157 | 90 | long expTime = System.currentTimeMillis() + Math.max(minTimeout, timeout); |
158 | 91 | UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID(); |
159 | 92 | boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean(); |
160 | - accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<DeferredResult<ResponseEntity>>() { | |
93 | + accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<>() { | |
161 | 94 | @Override |
162 | 95 | public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) { |
163 | 96 | ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID, |
... | ... | @@ -168,7 +101,7 @@ public class RpcController extends BaseController { |
168 | 101 | body, |
169 | 102 | persisted |
170 | 103 | ); |
171 | - deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse), currentUser); | |
104 | + deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse, timeoutStatus), currentUser); | |
172 | 105 | } |
173 | 106 | |
174 | 107 | @Override |
... | ... | @@ -184,12 +117,12 @@ public class RpcController extends BaseController { |
184 | 117 | } |
185 | 118 | })); |
186 | 119 | return response; |
187 | - } catch (IOException ioe) { | |
120 | + } catch (IllegalArgumentException ioe) { | |
188 | 121 | throw new ThingsboardException("Invalid request body", ioe, ThingsboardErrorCode.BAD_REQUEST_PARAMS); |
189 | 122 | } |
190 | 123 | } |
191 | 124 | |
192 | - public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response) { | |
125 | + public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response, HttpStatus timeoutStatus) { | |
193 | 126 | Optional<RpcError> rpcError = response.getError(); |
194 | 127 | DeferredResult<ResponseEntity> responseWriter = rpcRequest.getResponseWriter(); |
195 | 128 | if (rpcError.isPresent()) { |
... | ... | @@ -197,13 +130,13 @@ public class RpcController extends BaseController { |
197 | 130 | RpcError error = rpcError.get(); |
198 | 131 | switch (error) { |
199 | 132 | case TIMEOUT: |
200 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); | |
133 | + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); | |
201 | 134 | break; |
202 | 135 | case NO_ACTIVE_CONNECTION: |
203 | 136 | responseWriter.setResult(new ResponseEntity<>(HttpStatus.CONFLICT)); |
204 | 137 | break; |
205 | 138 | default: |
206 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); | |
139 | + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); | |
207 | 140 | break; |
208 | 141 | } |
209 | 142 | } else { |
... | ... | @@ -212,8 +145,8 @@ public class RpcController extends BaseController { |
212 | 145 | String data = responseData.get(); |
213 | 146 | try { |
214 | 147 | logRpcCall(rpcRequest, rpcError, null); |
215 | - responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); | |
216 | - } catch (IOException e) { | |
148 | + responseWriter.setResult(new ResponseEntity<>(JacksonUtil.toJsonNode(data), HttpStatus.OK)); | |
149 | + } catch (IllegalArgumentException e) { | |
217 | 150 | log.debug("Failed to decode device response: {}", data, e); |
218 | 151 | logRpcCall(rpcRequest, rpcError, e); |
219 | 152 | responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE)); | ... | ... |
1 | +package org.thingsboard.server.controller; | |
2 | + | |
3 | +import lombok.extern.slf4j.Slf4j; | |
4 | +import org.springframework.http.HttpStatus; | |
5 | +import org.springframework.http.ResponseEntity; | |
6 | +import org.springframework.security.access.prepost.PreAuthorize; | |
7 | +import org.springframework.web.bind.annotation.PathVariable; | |
8 | +import org.springframework.web.bind.annotation.RequestBody; | |
9 | +import org.springframework.web.bind.annotation.RequestMapping; | |
10 | +import org.springframework.web.bind.annotation.RequestMethod; | |
11 | +import org.springframework.web.bind.annotation.ResponseBody; | |
12 | +import org.springframework.web.bind.annotation.RestController; | |
13 | +import org.springframework.web.context.request.async.DeferredResult; | |
14 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | |
15 | +import org.thingsboard.server.common.data.id.DeviceId; | |
16 | +import org.thingsboard.server.queue.util.TbCoreComponent; | |
17 | + | |
18 | +import java.util.UUID; | |
19 | + | |
20 | +@RestController | |
21 | +@TbCoreComponent | |
22 | +@RequestMapping(TbUrlConstants.RPC_V1_URL_PREFIX) | |
23 | +@Slf4j | |
24 | +public class RpcV1Controller extends AbstractRpcController { | |
25 | + | |
26 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
27 | + @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) | |
28 | + @ResponseBody | |
29 | + public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
30 | + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT); | |
31 | + } | |
32 | + | |
33 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
34 | + @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) | |
35 | + @ResponseBody | |
36 | + public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
37 | + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT); | |
38 | + } | |
39 | + | |
40 | +} | ... | ... |
1 | +package org.thingsboard.server.controller; | |
2 | + | |
3 | +import lombok.extern.slf4j.Slf4j; | |
4 | +import org.springframework.http.HttpStatus; | |
5 | +import org.springframework.http.ResponseEntity; | |
6 | +import org.springframework.security.access.prepost.PreAuthorize; | |
7 | +import org.springframework.web.bind.annotation.PathVariable; | |
8 | +import org.springframework.web.bind.annotation.RequestBody; | |
9 | +import org.springframework.web.bind.annotation.RequestMapping; | |
10 | +import org.springframework.web.bind.annotation.RequestMethod; | |
11 | +import org.springframework.web.bind.annotation.RequestParam; | |
12 | +import org.springframework.web.bind.annotation.ResponseBody; | |
13 | +import org.springframework.web.bind.annotation.RestController; | |
14 | +import org.springframework.web.context.request.async.DeferredResult; | |
15 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | |
16 | +import org.thingsboard.server.common.data.id.DeviceId; | |
17 | +import org.thingsboard.server.common.data.id.RpcId; | |
18 | +import org.thingsboard.server.common.data.id.TenantId; | |
19 | +import org.thingsboard.server.common.data.page.PageData; | |
20 | +import org.thingsboard.server.common.data.page.PageLink; | |
21 | +import org.thingsboard.server.common.data.rpc.Rpc; | |
22 | +import org.thingsboard.server.common.data.rpc.RpcStatus; | |
23 | +import org.thingsboard.server.queue.util.TbCoreComponent; | |
24 | +import org.thingsboard.server.service.security.permission.Operation; | |
25 | + | |
26 | +import java.util.UUID; | |
27 | + | |
28 | +@RestController | |
29 | +@TbCoreComponent | |
30 | +@RequestMapping(TbUrlConstants.RPC_V2_URL_PREFIX) | |
31 | +@Slf4j | |
32 | +public class RpcV2Controller extends AbstractRpcController { | |
33 | + | |
34 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
35 | + @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) | |
36 | + @ResponseBody | |
37 | + public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
38 | + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT); | |
39 | + } | |
40 | + | |
41 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
42 | + @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) | |
43 | + @ResponseBody | |
44 | + public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | |
45 | + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT); | |
46 | + } | |
47 | + | |
48 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
49 | + @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) | |
50 | + @ResponseBody | |
51 | + public Rpc getPersistedRpc(@PathVariable("rpcId") String strRpc) throws ThingsboardException { | |
52 | + checkParameter("RpcId", strRpc); | |
53 | + try { | |
54 | + RpcId rpcId = new RpcId(UUID.fromString(strRpc)); | |
55 | + return checkRpcId(rpcId, Operation.READ); | |
56 | + } catch (Exception e) { | |
57 | + throw handleException(e); | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
62 | + @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) | |
63 | + @ResponseBody | |
64 | + public PageData<Rpc> getPersistedRpcByDevice(@PathVariable("deviceId") String strDeviceId, | |
65 | + @RequestParam int pageSize, | |
66 | + @RequestParam int page, | |
67 | + @RequestParam RpcStatus rpcStatus, | |
68 | + @RequestParam(required = false) String textSearch, | |
69 | + @RequestParam(required = false) String sortProperty, | |
70 | + @RequestParam(required = false) String sortOrder) throws ThingsboardException { | |
71 | + checkParameter("DeviceId", strDeviceId); | |
72 | + try { | |
73 | + TenantId tenantId = getCurrentUser().getTenantId(); | |
74 | + PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); | |
75 | + DeviceId deviceId = new DeviceId(UUID.fromString(strDeviceId)); | |
76 | + return checkNotNull(rpcService.findAllByDeviceIdAndStatus(tenantId, deviceId, rpcStatus, pageLink)); | |
77 | + } catch (Exception e) { | |
78 | + throw handleException(e); | |
79 | + } | |
80 | + } | |
81 | + | |
82 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") | |
83 | + @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) | |
84 | + @ResponseBody | |
85 | + public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { | |
86 | + checkParameter("RpcId", strRpc); | |
87 | + try { | |
88 | + rpcService.deleteRpc(getTenantId(), new RpcId(UUID.fromString(strRpc))); | |
89 | + } catch (Exception e) { | |
90 | + throw handleException(e); | |
91 | + } | |
92 | + } | |
93 | +} | ... | ... |
... | ... | @@ -20,5 +20,6 @@ package org.thingsboard.server.controller; |
20 | 20 | */ |
21 | 21 | public class TbUrlConstants { |
22 | 22 | public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry"; |
23 | - public static final String RPC_URL_PREFIX = "/api/plugins/rpc"; | |
23 | + public static final String RPC_V1_URL_PREFIX = "/api/plugins/rpc"; | |
24 | + public static final String RPC_V2_URL_PREFIX = "/api/rpc"; | |
24 | 25 | } | ... | ... |
... | ... | @@ -43,7 +43,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab |
43 | 43 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; |
44 | 44 | String deviceId = savedDevice.getId().getId().toString(); |
45 | 45 | |
46 | - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), | |
46 | + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), | |
47 | 47 | asyncContextTimeoutToUseRpcPlugin); |
48 | 48 | } |
49 | 49 | |
... | ... | @@ -52,7 +52,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab |
52 | 52 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; |
53 | 53 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
54 | 54 | |
55 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
55 | + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
56 | 56 | status().isNotFound()); |
57 | 57 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
58 | 58 | } |
... | ... | @@ -62,7 +62,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab |
62 | 62 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; |
63 | 63 | String deviceId = savedDevice.getId().getId().toString(); |
64 | 64 | |
65 | - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), | |
65 | + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), | |
66 | 66 | asyncContextTimeoutToUseRpcPlugin); |
67 | 67 | } |
68 | 68 | |
... | ... | @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab |
71 | 71 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; |
72 | 72 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
73 | 73 | |
74 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
74 | + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
75 | 75 | status().isNotFound()); |
76 | 76 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
77 | 77 | } | ... | ... |
... | ... | @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC |
71 | 71 | |
72 | 72 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
73 | 73 | String deviceId = savedDevice.getId().getId().toString(); |
74 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
74 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
75 | 75 | |
76 | 76 | latch.await(3, TimeUnit.SECONDS); |
77 | 77 | |
... | ... | @@ -99,14 +99,14 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC |
99 | 99 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
100 | 100 | String deviceId = savedDevice.getId().getId().toString(); |
101 | 101 | |
102 | - String actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
102 | + String actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
103 | 103 | latch.await(3, TimeUnit.SECONDS); |
104 | 104 | |
105 | 105 | validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult); |
106 | 106 | |
107 | 107 | latch = new CountDownLatch(1); |
108 | 108 | |
109 | - actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
109 | + actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
110 | 110 | latch.await(3, TimeUnit.SECONDS); |
111 | 111 | |
112 | 112 | validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult); | ... | ... |
... | ... | @@ -46,7 +46,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab |
46 | 46 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; |
47 | 47 | String deviceId = savedDevice.getId().getId().toString(); |
48 | 48 | |
49 | - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), | |
49 | + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), | |
50 | 50 | asyncContextTimeoutToUseRpcPlugin); |
51 | 51 | } |
52 | 52 | |
... | ... | @@ -55,7 +55,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab |
55 | 55 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; |
56 | 56 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
57 | 57 | |
58 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
58 | + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
59 | 59 | status().isNotFound()); |
60 | 60 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
61 | 61 | } |
... | ... | @@ -65,7 +65,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab |
65 | 65 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; |
66 | 66 | String deviceId = savedDevice.getId().getId().toString(); |
67 | 67 | |
68 | - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), | |
68 | + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), | |
69 | 69 | asyncContextTimeoutToUseRpcPlugin); |
70 | 70 | } |
71 | 71 | |
... | ... | @@ -74,7 +74,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab |
74 | 74 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; |
75 | 75 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
76 | 76 | |
77 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
77 | + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | |
78 | 78 | status().isNotFound()); |
79 | 79 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
80 | 80 | } | ... | ... |
... | ... | @@ -69,7 +69,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM |
69 | 69 | |
70 | 70 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
71 | 71 | String deviceId = savedDevice.getId().getId().toString(); |
72 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
72 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
73 | 73 | Assert.assertTrue(StringUtils.isEmpty(result)); |
74 | 74 | latch.await(3, TimeUnit.SECONDS); |
75 | 75 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); |
... | ... | @@ -95,7 +95,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM |
95 | 95 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
96 | 96 | String deviceId = savedDevice.getId().getId().toString(); |
97 | 97 | |
98 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
98 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
99 | 99 | String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; |
100 | 100 | latch.await(3, TimeUnit.SECONDS); |
101 | 101 | Assert.assertEquals(expected, result); |
... | ... | @@ -130,7 +130,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM |
130 | 130 | |
131 | 131 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; |
132 | 132 | String deviceId = savedDevice.getId().getId().toString(); |
133 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
133 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
134 | 134 | Assert.assertTrue(StringUtils.isEmpty(result)); |
135 | 135 | latch.await(3, TimeUnit.SECONDS); |
136 | 136 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); |
... | ... | @@ -156,7 +156,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM |
156 | 156 | |
157 | 157 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; |
158 | 158 | String deviceId = savedDevice.getId().getId().toString(); |
159 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
159 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
160 | 160 | latch.await(3, TimeUnit.SECONDS); |
161 | 161 | String expected = "{\"success\":true}"; |
162 | 162 | assertEquals(expected, result); | ... | ... |
... | ... | @@ -131,7 +131,7 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst |
131 | 131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
132 | 132 | String deviceId = savedDevice.getId().getId().toString(); |
133 | 133 | |
134 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
134 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
135 | 135 | String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; |
136 | 136 | latch.await(3, TimeUnit.SECONDS); |
137 | 137 | Assert.assertEquals(expected, result); | ... | ... |
... | ... | @@ -267,7 +267,7 @@ public class MqttClientTest extends AbstractContainerTest { |
267 | 267 | ListenableFuture<ResponseEntity> future = service.submit(() -> { |
268 | 268 | try { |
269 | 269 | return restClient.getRestTemplate() |
270 | - .postForEntity(HTTPS_URL + "/api/plugins/rpc/twoway/{deviceId}", | |
270 | + .postForEntity(HTTPS_URL + "/api/rpc/twoway/{deviceId}", | |
271 | 271 | mapper.readTree(serverRpcPayload.toString()), String.class, |
272 | 272 | device.getId()); |
273 | 273 | } catch (IOException e) { | ... | ... |
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java
... | ... | @@ -263,7 +263,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest { |
263 | 263 | ListenableFuture<ResponseEntity> future = service.submit(() -> { |
264 | 264 | try { |
265 | 265 | return restClient.getRestTemplate() |
266 | - .postForEntity(HTTPS_URL + "/api/plugins/rpc/twoway/{deviceId}", | |
266 | + .postForEntity(HTTPS_URL + "/api/rpc/twoway/{deviceId}", | |
267 | 267 | mapper.readTree(serverRpcPayload.toString()), String.class, |
268 | 268 | createdDevice.getId()); |
269 | 269 | } catch (IOException e) { | ... | ... |
... | ... | @@ -1811,12 +1811,12 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { |
1811 | 1811 | } |
1812 | 1812 | |
1813 | 1813 | public void handleOneWayDeviceRPCRequest(DeviceId deviceId, JsonNode requestBody) { |
1814 | - restTemplate.postForLocation(baseURL + "/api/plugins/rpc/oneway/{deviceId}", requestBody, deviceId.getId()); | |
1814 | + restTemplate.postForLocation(baseURL + "/api/rpc/oneway/{deviceId}", requestBody, deviceId.getId()); | |
1815 | 1815 | } |
1816 | 1816 | |
1817 | 1817 | public JsonNode handleTwoWayDeviceRPCRequest(DeviceId deviceId, JsonNode requestBody) { |
1818 | 1818 | return restTemplate.exchange( |
1819 | - baseURL + "/api/plugins/rpc/twoway/{deviceId}", | |
1819 | + baseURL + "/api/rpc/twoway/{deviceId}", | |
1820 | 1820 | HttpMethod.POST, |
1821 | 1821 | new HttpEntity<>(requestBody), |
1822 | 1822 | new ParameterizedTypeReference<JsonNode>() { | ... | ... |
... | ... | @@ -130,11 +130,11 @@ export class DeviceService { |
130 | 130 | } |
131 | 131 | |
132 | 132 | public sendOneWayRpcCommand(deviceId: string, requestBody: any, config?: RequestConfig): Observable<any> { |
133 | - return this.http.post<Device>(`/api/plugins/rpc/oneway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); | |
133 | + return this.http.post<Device>(`/api/rpc/oneway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); | |
134 | 134 | } |
135 | 135 | |
136 | 136 | public sendTwoWayRpcCommand(deviceId: string, requestBody: any, config?: RequestConfig): Observable<any> { |
137 | - return this.http.post<Device>(`/api/plugins/rpc/twoway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); | |
137 | + return this.http.post<Device>(`/api/rpc/twoway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); | |
138 | 138 | } |
139 | 139 | |
140 | 140 | public findByQuery(query: DeviceSearchQuery, | ... | ... |
... | ... | @@ -47,7 +47,7 @@ export class GlobalHttpInterceptor implements HttpInterceptor { |
47 | 47 | |
48 | 48 | private internalUrlPrefixes = [ |
49 | 49 | '/api/auth/token', |
50 | - '/api/plugins/rpc' | |
50 | + '/api/rpc' | |
51 | 51 | ]; |
52 | 52 | |
53 | 53 | private activeRequests = 0; |
... | ... | @@ -142,7 +142,7 @@ export class GlobalHttpInterceptor implements HttpInterceptor { |
142 | 142 | } |
143 | 143 | } else if (errorResponse.status === 0 || errorResponse.status === -1) { |
144 | 144 | this.showError('Unable to connect'); |
145 | - } else if (!req.url.startsWith('/api/plugins/rpc')) { | |
145 | + } else if (!req.url.startsWith('/api/plugins/rpc') && !req.url.startsWith('/api/rpc')) { | |
146 | 146 | if (errorResponse.status === 404) { |
147 | 147 | if (!ignoreErrors) { |
148 | 148 | this.showError(req.method + ': ' + req.url + '<br/>' + | ... | ... |