Commit 65ad86bedb3713d896707edb86a83dfaf1bad51d

Authored by Andrii Shvaika
1 parent 940c81b0

RPC v2 to switch from 409 to 504 error code

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) {
... ...
... ... @@ -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/>' +
... ...