diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java similarity index 65% rename from application/src/main/java/org/thingsboard/server/controller/RpcController.java rename to application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java index 50ab5c7863..d03ef1770d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,7 +16,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.FutureCallback; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -26,13 +25,12 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.audit.ActionType; @@ -59,20 +57,15 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity; import javax.annotation.Nullable; -import java.io.IOException; import java.util.Optional; import java.util.UUID; /** * Created by ashvayka on 22.03.18. */ -@RestController @TbCoreComponent -@RequestMapping(TbUrlConstants.RPC_URL_PREFIX) @Slf4j -public class RpcController extends BaseController { - - protected final ObjectMapper jsonMapper = new ObjectMapper(); +public abstract class AbstractRpcController extends BaseController { @Autowired private TbCoreDeviceRpcService deviceRpcService; @@ -81,75 +74,15 @@ public class RpcController extends BaseController { private AccessValidator accessValidator; @Value("${server.rest.server_side_rpc.min_timeout:5000}") - private long minTimeout; + protected long minTimeout; @Value("${server.rest.server_side_rpc.default_timeout:10000}") - private long defaultTimeout; + protected long defaultTimeout; - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) - @ResponseBody - public DeferredResult handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { - return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); - } - - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) - @ResponseBody - public DeferredResult handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { - return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) - @ResponseBody - public Rpc getPersistedRpc(@PathVariable("rpcId") String strRpc) throws ThingsboardException { - checkParameter("RpcId", strRpc); + protected DeferredResult handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody, HttpStatus timeoutStatus) throws ThingsboardException { try { - RpcId rpcId = new RpcId(UUID.fromString(strRpc)); - return checkRpcId(rpcId, Operation.READ); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) - @ResponseBody - public PageData getPersistedRpcByDevice(@PathVariable("deviceId") String strDeviceId, - @RequestParam int pageSize, - @RequestParam int page, - @RequestParam RpcStatus rpcStatus, - @RequestParam(required = false) String textSearch, - @RequestParam(required = false) String sortProperty, - @RequestParam(required = false) String sortOrder) throws ThingsboardException { - checkParameter("DeviceId", strDeviceId); - try { - TenantId tenantId = getCurrentUser().getTenantId(); - PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); - DeviceId deviceId = new DeviceId(UUID.fromString(strDeviceId)); - return checkNotNull(rpcService.findAllByDeviceIdAndStatus(tenantId, deviceId, rpcStatus, pageLink)); - } catch (Exception e) { - throw handleException(e); - } - } - - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) - @ResponseBody - public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { - checkParameter("RpcId", strRpc); - try { - rpcService.deleteRpc(getTenantId(), new RpcId(UUID.fromString(strRpc))); - } catch (Exception e) { - throw handleException(e); - } - } - - private DeferredResult handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody) throws ThingsboardException { - try { - JsonNode rpcRequestBody = jsonMapper.readTree(requestBody); - ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), jsonMapper.writeValueAsString(rpcRequestBody.get("params"))); + JsonNode rpcRequestBody = JacksonUtil.toJsonNode(requestBody); + ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), JacksonUtil.toString(rpcRequestBody.get("params"))); SecurityUser currentUser = getCurrentUser(); TenantId tenantId = currentUser.getTenantId(); final DeferredResult response = new DeferredResult<>(); @@ -157,7 +90,7 @@ public class RpcController extends BaseController { long expTime = System.currentTimeMillis() + Math.max(minTimeout, timeout); UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID(); boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean(); - accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback>() { + accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<>() { @Override public void onSuccess(@Nullable DeferredResult result) { ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID, @@ -168,7 +101,7 @@ public class RpcController extends BaseController { body, persisted ); - deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse), currentUser); + deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse, timeoutStatus), currentUser); } @Override @@ -184,12 +117,12 @@ public class RpcController extends BaseController { } })); return response; - } catch (IOException ioe) { + } catch (IllegalArgumentException ioe) { throw new ThingsboardException("Invalid request body", ioe, ThingsboardErrorCode.BAD_REQUEST_PARAMS); } } - public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response) { + public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response, HttpStatus timeoutStatus) { Optional rpcError = response.getError(); DeferredResult responseWriter = rpcRequest.getResponseWriter(); if (rpcError.isPresent()) { @@ -197,13 +130,13 @@ public class RpcController extends BaseController { RpcError error = rpcError.get(); switch (error) { case TIMEOUT: - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); break; case NO_ACTIVE_CONNECTION: responseWriter.setResult(new ResponseEntity<>(HttpStatus.CONFLICT)); break; default: - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); break; } } else { @@ -212,8 +145,8 @@ public class RpcController extends BaseController { String data = responseData.get(); try { logRpcCall(rpcRequest, rpcError, null); - responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); - } catch (IOException e) { + responseWriter.setResult(new ResponseEntity<>(JacksonUtil.toJsonNode(data), HttpStatus.OK)); + } catch (IllegalArgumentException e) { log.debug("Failed to decode device response: {}", data, e); logRpcCall(rpcRequest, rpcError, e); responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java new file mode 100644 index 0000000000..344e17b108 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java @@ -0,0 +1,40 @@ +package org.thingsboard.server.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.UUID; + +@RestController +@TbCoreComponent +@RequestMapping(TbUrlConstants.RPC_V1_URL_PREFIX) +@Slf4j +public class RpcV1Controller extends AbstractRpcController { + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) + @ResponseBody + public DeferredResult handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT); + } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) + @ResponseBody + public DeferredResult handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT); + } + +} diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java new file mode 100644 index 0000000000..48d7dc7c44 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java @@ -0,0 +1,93 @@ +package org.thingsboard.server.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.RpcId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.rpc.Rpc; +import org.thingsboard.server.common.data.rpc.RpcStatus; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.permission.Operation; + +import java.util.UUID; + +@RestController +@TbCoreComponent +@RequestMapping(TbUrlConstants.RPC_V2_URL_PREFIX) +@Slf4j +public class RpcV2Controller extends AbstractRpcController { + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) + @ResponseBody + public DeferredResult handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT); + } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) + @ResponseBody + public DeferredResult handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT); + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) + @ResponseBody + public Rpc getPersistedRpc(@PathVariable("rpcId") String strRpc) throws ThingsboardException { + checkParameter("RpcId", strRpc); + try { + RpcId rpcId = new RpcId(UUID.fromString(strRpc)); + return checkRpcId(rpcId, Operation.READ); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) + @ResponseBody + public PageData getPersistedRpcByDevice(@PathVariable("deviceId") String strDeviceId, + @RequestParam int pageSize, + @RequestParam int page, + @RequestParam RpcStatus rpcStatus, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String sortProperty, + @RequestParam(required = false) String sortOrder) throws ThingsboardException { + checkParameter("DeviceId", strDeviceId); + try { + TenantId tenantId = getCurrentUser().getTenantId(); + PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); + DeviceId deviceId = new DeviceId(UUID.fromString(strDeviceId)); + return checkNotNull(rpcService.findAllByDeviceIdAndStatus(tenantId, deviceId, rpcStatus, pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) + @ResponseBody + public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { + checkParameter("RpcId", strRpc); + try { + rpcService.deleteRpc(getTenantId(), new RpcId(UUID.fromString(strRpc))); + } catch (Exception e) { + throw handleException(e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java b/application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java index 0ba1a87971..4b5e52a594 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java @@ -20,5 +20,6 @@ package org.thingsboard.server.controller; */ public class TbUrlConstants { public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry"; - public static final String RPC_URL_PREFIX = "/api/plugins/rpc"; + public static final String RPC_V1_URL_PREFIX = "/api/plugins/rpc"; + public static final String RPC_V2_URL_PREFIX = "/api/rpc"; } diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java index 3c47b2497e..2a5e46473a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java @@ -43,7 +43,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; String deviceId = savedDevice.getId().getId().toString(); - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), asyncContextTimeoutToUseRpcPlugin); } @@ -52,7 +52,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; String nonExistentDeviceId = Uuids.timeBased().toString(); - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().isNotFound()); Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); } @@ -62,7 +62,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; String deviceId = savedDevice.getId().getId().toString(); - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), asyncContextTimeoutToUseRpcPlugin); } @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; String nonExistentDeviceId = Uuids.timeBased().toString(); - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, status().isNotFound()); Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); } diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java index e2567576f3..758dc02004 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); latch.await(3, TimeUnit.SECONDS); @@ -99,14 +99,14 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); latch.await(3, TimeUnit.SECONDS); validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult); latch = new CountDownLatch(1); - actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); latch.await(3, TimeUnit.SECONDS); validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcDefaultIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcDefaultIntegrationTest.java index 32f770a41c..b5f005cd00 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcDefaultIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcDefaultIntegrationTest.java @@ -46,7 +46,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; String deviceId = savedDevice.getId().getId().toString(); - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), asyncContextTimeoutToUseRpcPlugin); } @@ -55,7 +55,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; String nonExistentDeviceId = Uuids.timeBased().toString(); - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().isNotFound()); Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); } @@ -65,7 +65,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; String deviceId = savedDevice.getId().getId().toString(); - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), asyncContextTimeoutToUseRpcPlugin); } @@ -74,7 +74,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; String nonExistentDeviceId = Uuids.timeBased().toString(); - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, status().isNotFound()); Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java index f24cb0c2bc..9f83f24bcb 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -69,7 +69,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); Assert.assertTrue(StringUtils.isEmpty(result)); latch.await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); @@ -95,7 +95,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; latch.await(3, TimeUnit.SECONDS); Assert.assertEquals(expected, result); @@ -130,7 +130,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); Assert.assertTrue(StringUtils.isEmpty(result)); latch.await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); @@ -156,7 +156,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); latch.await(3, TimeUnit.SECONDS); String expected = "{\"success\":true}"; assertEquals(expected, result); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcProtoIntegrationTest.java index cf9ae499c4..3792d66ac4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcProtoIntegrationTest.java @@ -131,7 +131,7 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; latch.await(3, TimeUnit.SECONDS); Assert.assertEquals(expected, result); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java index c8156b6ef1..7ae8f863af 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java @@ -267,7 +267,7 @@ public class MqttClientTest extends AbstractContainerTest { ListenableFuture future = service.submit(() -> { try { return restClient.getRestTemplate() - .postForEntity(HTTPS_URL + "/api/plugins/rpc/twoway/{deviceId}", + .postForEntity(HTTPS_URL + "/api/rpc/twoway/{deviceId}", mapper.readTree(serverRpcPayload.toString()), String.class, device.getId()); } catch (IOException e) { diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java index a059957d6b..def365dcb1 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java @@ -263,7 +263,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest { ListenableFuture future = service.submit(() -> { try { return restClient.getRestTemplate() - .postForEntity(HTTPS_URL + "/api/plugins/rpc/twoway/{deviceId}", + .postForEntity(HTTPS_URL + "/api/rpc/twoway/{deviceId}", mapper.readTree(serverRpcPayload.toString()), String.class, createdDevice.getId()); } catch (IOException e) { diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index d32552f63d..9c0ceccf00 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -1811,12 +1811,12 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { } public void handleOneWayDeviceRPCRequest(DeviceId deviceId, JsonNode requestBody) { - restTemplate.postForLocation(baseURL + "/api/plugins/rpc/oneway/{deviceId}", requestBody, deviceId.getId()); + restTemplate.postForLocation(baseURL + "/api/rpc/oneway/{deviceId}", requestBody, deviceId.getId()); } public JsonNode handleTwoWayDeviceRPCRequest(DeviceId deviceId, JsonNode requestBody) { return restTemplate.exchange( - baseURL + "/api/plugins/rpc/twoway/{deviceId}", + baseURL + "/api/rpc/twoway/{deviceId}", HttpMethod.POST, new HttpEntity<>(requestBody), new ParameterizedTypeReference() { diff --git a/ui-ngx/src/app/core/http/device.service.ts b/ui-ngx/src/app/core/http/device.service.ts index 04cf633e53..682dcc3620 100644 --- a/ui-ngx/src/app/core/http/device.service.ts +++ b/ui-ngx/src/app/core/http/device.service.ts @@ -130,11 +130,11 @@ export class DeviceService { } public sendOneWayRpcCommand(deviceId: string, requestBody: any, config?: RequestConfig): Observable { - return this.http.post(`/api/plugins/rpc/oneway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); + return this.http.post(`/api/rpc/oneway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); } public sendTwoWayRpcCommand(deviceId: string, requestBody: any, config?: RequestConfig): Observable { - return this.http.post(`/api/plugins/rpc/twoway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); + return this.http.post(`/api/rpc/twoway/${deviceId}`, requestBody, defaultHttpOptionsFromConfig(config)); } public findByQuery(query: DeviceSearchQuery, diff --git a/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts b/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts index 5449cac3e1..54be9bb24c 100644 --- a/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts +++ b/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts @@ -47,7 +47,7 @@ export class GlobalHttpInterceptor implements HttpInterceptor { private internalUrlPrefixes = [ '/api/auth/token', - '/api/plugins/rpc' + '/api/rpc' ]; private activeRequests = 0; @@ -142,7 +142,7 @@ export class GlobalHttpInterceptor implements HttpInterceptor { } } else if (errorResponse.status === 0 || errorResponse.status === -1) { this.showError('Unable to connect'); - } else if (!req.url.startsWith('/api/plugins/rpc')) { + } else if (!req.url.startsWith('/api/plugins/rpc') && !req.url.startsWith('/api/rpc')) { if (errorResponse.status === 404) { if (!ignoreErrors) { this.showError(req.method + ': ' + req.url + '
' +