diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java index 04b1b4c522..23985f3975 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java @@ -31,7 +31,9 @@ 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.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.dao.device.DeviceConnectivityService; @@ -87,6 +89,36 @@ public class DeviceConnectivityController extends BaseController { return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device); } + @ApiOperation(value = "Get commands to launch gateway (getGatewayLaunchCommands)", + notes = "Fetch the list of commands for different operation systems to launch a gateway using docker." + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK", + examples = @io.swagger.annotations.Example( + value = { + @io.swagger.annotations.ExampleProperty( + mediaType = "application/json", + value = "{\"mqtt\": {\n" + + " \"linux\": \"docker run --rm -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v ~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\",\n" + + " \"windows\": \"docker run --rm -it -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs -v %HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\"}\n" + + "}")}))}) + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/device-connectivity/gateway-launch/{deviceId}", method = RequestMethod.GET) + @ResponseBody + public JsonNode getGatewayLaunchCommands(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException { + checkParameter(DEVICE_ID, strDeviceId); + DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); + Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS); + + if (!checkIsGateway(device)) { + throw new ThingsboardException("The device must be a gateway!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); + } + + String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request); + return deviceConnectivityService.findGatewayLaunchCommands(baseUrl, device); + } + @ApiOperation(value = "Download server certificate using file path defined in device.connectivity properties (downloadServerCertificate)", notes = "Download server certificate.") @RequestMapping(value = "/device-connectivity/{protocol}/certificate/download", method = RequestMethod.GET) @ResponseBody @@ -104,4 +136,8 @@ public class DeviceConnectivityController extends BaseController { .body(pemCert); } + private static boolean checkIsGateway(Device device) { + return device.getAdditionalInfo().has(DataConstants.GATEWAY_PARAMETER) && + device.getAdditionalInfo().get(DataConstants.GATEWAY_PARAMETER).asBoolean(); + } } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java index 90355d885d..4f2d9a1aee 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityService.java @@ -25,5 +25,7 @@ public interface DeviceConnectivityService { JsonNode findDevicePublishTelemetryCommands(String baseUrl, Device device) throws URISyntaxException; + JsonNode findGatewayLaunchCommands(String baseUrl, Device device) throws URISyntaxException; + Resource getPemCertFile(String protocol); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityServiceImpl.java index 1d1c627a66..8c4faa2b8c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityServiceImpl.java @@ -19,13 +19,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; @@ -48,7 +46,6 @@ import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.CHECK_DOCUM import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAP; import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.COAPS; import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.DOCKER; -import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.GATEWAY; import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.HTTP; import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.HTTPS; import static org.thingsboard.server.dao.util.DeviceConnectivityUtil.LINUX; @@ -84,12 +81,6 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService DeviceTransportType transportType = deviceProfile.getTransportType(); ObjectNode commands = JacksonUtil.newObjectNode(); - if (checkIsGateway(device)) { - Optional.ofNullable(getMqttTransportPublishCommands(baseUrl, creds, true)) - .ifPresent(v -> commands.set(MQTT, v)); - return commands; - } - switch (transportType) { case DEFAULT: Optional.ofNullable(getHttpTransportPublishCommands(baseUrl, creds)) @@ -124,6 +115,26 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService return commands; } + @Override + public JsonNode findGatewayLaunchCommands(String baseUrl, Device device) throws URISyntaxException { + DeviceId deviceId = device.getId(); + log.trace("Executing findDevicePublishTelemetryCommands [{}]", deviceId); + validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); + + DeviceCredentials creds = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), deviceId); + + ObjectNode commands = JacksonUtil.newObjectNode(); + if (deviceConnectivityConfiguration.isEnabled(MQTT)) { + Optional.ofNullable(getGatewayDockerCommands(baseUrl, creds, MQTT)) + .ifPresent(v -> commands.set(MQTT, v)); + } + if (deviceConnectivityConfiguration.isEnabled(MQTTS)) { + Optional.ofNullable(getGatewayDockerCommands(baseUrl, creds, MQTTS)) + .ifPresent(v -> commands.set(MQTTS, v)); + } + return commands; + } + @Override public Resource getPemCertFile(String protocol) { String certFilePath = deviceConnectivityConfiguration.getConnectivity() @@ -159,18 +170,10 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService } private JsonNode getMqttTransportPublishCommands(String baseUrl, DeviceCredentials deviceCredentials) throws URISyntaxException { - return getMqttTransportPublishCommands(baseUrl, deviceCredentials, false); - } - - private JsonNode getMqttTransportPublishCommands(String baseUrl, DeviceCredentials deviceCredentials, boolean isGateway) throws URISyntaxException { - return getMqttTransportPublishCommands(baseUrl, DEFAULT_DEVICE_TELEMETRY_TOPIC, deviceCredentials, isGateway); + return getMqttTransportPublishCommands(baseUrl, DEFAULT_DEVICE_TELEMETRY_TOPIC, deviceCredentials); } private JsonNode getMqttTransportPublishCommands(String baseUrl, String topic, DeviceCredentials deviceCredentials) throws URISyntaxException { - return getMqttTransportPublishCommands(baseUrl, topic, deviceCredentials, false); - } - - private JsonNode getMqttTransportPublishCommands(String baseUrl, String topic, DeviceCredentials deviceCredentials, boolean isGateway) throws URISyntaxException { ObjectNode mqttCommands = JacksonUtil.newObjectNode(); if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { @@ -179,7 +182,6 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService } ObjectNode dockerMqttCommands = JacksonUtil.newObjectNode(); - ObjectNode gatewayDockerMqttCommands = JacksonUtil.newObjectNode(); if (deviceConnectivityConfiguration.isEnabled(MQTT)) { Optional.ofNullable(getMqttPublishCommand(baseUrl, topic, deviceCredentials)). @@ -187,11 +189,6 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService Optional.ofNullable(getDockerMqttPublishCommand(MQTT, baseUrl, topic, deviceCredentials)) .ifPresent(v -> dockerMqttCommands.put(MQTT, v)); - - if (isGateway) { - Optional.ofNullable(getGatewayDockerCommands(baseUrl, deviceCredentials, MQTT)) - .ifPresent(v -> gatewayDockerMqttCommands.set(MQTT, v)); - } } if (deviceConnectivityConfiguration.isEnabled(MQTTS)) { @@ -203,21 +200,11 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService Optional.ofNullable(getDockerMqttPublishCommand(MQTTS, baseUrl, topic, deviceCredentials)) .ifPresent(v -> dockerMqttCommands.put(MQTTS, v)); - - if (isGateway) { - Optional.ofNullable(getGatewayDockerCommands(baseUrl, deviceCredentials, MQTTS)) - .ifPresent(v -> gatewayDockerMqttCommands.set(MQTTS, v)); - } } if (!dockerMqttCommands.isEmpty()) { mqttCommands.set(DOCKER, dockerMqttCommands); } - - if (!gatewayDockerMqttCommands.isEmpty()) { - mqttCommands.set(GATEWAY, gatewayDockerMqttCommands); - } - return mqttCommands.isEmpty() ? null : mqttCommands; } @@ -313,8 +300,4 @@ public class DeviceConnectivityServiceImpl implements DeviceConnectivityService return properties.getHost().isEmpty() ? new URI(baseUrl).getHost() : properties.getHost(); } - private static boolean checkIsGateway(Device device) { - return device.getAdditionalInfo().has(DataConstants.GATEWAY_PARAMETER) && - device.getAdditionalInfo().get(DataConstants.GATEWAY_PARAMETER).asBoolean(); - } }