Refactored to use persistent RPC
This commit is contained in:
		
							parent
							
								
									5d6ac71e24
								
							
						
					
					
						commit
						b82c27f4f7
					
				@ -15,104 +15,67 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.gateway_device;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.core.type.TypeReference;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ArrayNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.TextNode;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.common.util.DonAsynchron;
 | 
			
		||||
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.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.JsonDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.KvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
			
		||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
 | 
			
		||||
import org.thingsboard.server.dao.attributes.AttributesService;
 | 
			
		||||
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
 | 
			
		||||
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
 | 
			
		||||
import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.dao.relation.RelationService;
 | 
			
		||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
 | 
			
		||||
import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Service
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class DefaultGatewayDeviceStateService implements GatewayDeviceStateService {
 | 
			
		||||
 | 
			
		||||
    private static final String RENAMED_GATEWAY_DEVICES = "renamedGatewayDevices";
 | 
			
		||||
    private static final String DELETED_GATEWAY_DEVICES = "deletedGatewayDevices";
 | 
			
		||||
    private static final String HANDLE_DEVICE_RENAMING_PARAMETER = "handleDeviceRenaming";
 | 
			
		||||
    private final static String DEVICE_RENAMED_METHOD_NAME = "gateway_device_renamed";
 | 
			
		||||
    private final static String DEVICE_DELETED_METHOD_NAME = "gateway_device_deleted";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Value("${server.rest.server_side_rpc.min_timeout:5000}")
 | 
			
		||||
    protected long minTimeout;
 | 
			
		||||
 | 
			
		||||
    @Value("${server.rest.server_side_rpc.default_timeout:10000}")
 | 
			
		||||
    protected long defaultTimeout;
 | 
			
		||||
 | 
			
		||||
    private final AttributesService attributesService;
 | 
			
		||||
    private final RelationService relationService;
 | 
			
		||||
    private final DeviceService deviceService;
 | 
			
		||||
 | 
			
		||||
    @Lazy
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private TelemetrySubscriptionService tsSubService;
 | 
			
		||||
    private TbCoreDeviceRpcService deviceRpcService;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update(Device device, Device oldDevice) {
 | 
			
		||||
        List<EntityRelation> relationToGatewayList = relationService.findByFromAndType(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.LAST_CONNECTED_GATEWAY, RelationTypeGroup.COMMON);
 | 
			
		||||
        if (!relationToGatewayList.isEmpty()) {
 | 
			
		||||
            if (oldDevice != null) {
 | 
			
		||||
                EntityRelation relationToGateway = relationToGatewayList.get(0);
 | 
			
		||||
 | 
			
		||||
                Device gatewayDevice = deviceService.findDeviceById(device.getTenantId(), (DeviceId) relationToGateway.getTo());
 | 
			
		||||
                if (isHandleDeviceRenamingEnabled(gatewayDevice.getAdditionalInfo())) {
 | 
			
		||||
                    ListenableFuture<List<AttributeKvEntry>> renamedGatewayDevicesFuture = attributesService.find(device.getTenantId(), relationToGateway.getTo(), DataConstants.SHARED_SCOPE, Collections.singletonList("renamedGatewayDevices"));
 | 
			
		||||
                    DonAsynchron.withCallback(renamedGatewayDevicesFuture, renamedGatewayDevicesList -> {
 | 
			
		||||
                                ObjectNode renamedGatewayDevicesNode;
 | 
			
		||||
                                KvEntry renamedGatewayDevicesKvEntry;
 | 
			
		||||
                                String newDeviceName = device.getName();
 | 
			
		||||
                                String oldDeviceName = oldDevice.getName();
 | 
			
		||||
 | 
			
		||||
                                if (renamedGatewayDevicesList.isEmpty()) {
 | 
			
		||||
                                    renamedGatewayDevicesNode = JacksonUtil.newObjectNode();
 | 
			
		||||
                                    renamedGatewayDevicesNode.put(oldDeviceName, newDeviceName);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    AttributeKvEntry receivedRenamedGatewayDevicesAttribute = renamedGatewayDevicesList.get(0);
 | 
			
		||||
                                    renamedGatewayDevicesNode = (ObjectNode) JacksonUtil.toJsonNode(receivedRenamedGatewayDevicesAttribute.getValueAsString());
 | 
			
		||||
                                    if (renamedGatewayDevicesNode.findValue(newDeviceName) != null && oldDeviceName.equals(renamedGatewayDevicesNode.get(newDeviceName).asText())) {
 | 
			
		||||
                                        // If a new device name is the same like the first name or another device was renamed like some existing device
 | 
			
		||||
                                        renamedGatewayDevicesNode.remove(newDeviceName);
 | 
			
		||||
                                    } else {
 | 
			
		||||
 | 
			
		||||
                                        AtomicBoolean renamedFirstTime = new AtomicBoolean(true);
 | 
			
		||||
 | 
			
		||||
                                        renamedGatewayDevicesNode.fields().forEachRemaining(entry -> {
 | 
			
		||||
                                            // If device was renamed earlier
 | 
			
		||||
                                            if (oldDeviceName.equals(entry.getValue().asText())) {
 | 
			
		||||
                                                renamedGatewayDevicesNode.put(entry.getKey(), newDeviceName);
 | 
			
		||||
                                                renamedFirstTime.set(false);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        });
 | 
			
		||||
                                        if (renamedFirstTime.get()) {
 | 
			
		||||
                                            renamedGatewayDevicesNode.put(oldDeviceName, newDeviceName);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                renamedGatewayDevicesKvEntry = new JsonDataEntry(RENAMED_GATEWAY_DEVICES, JacksonUtil.toString(renamedGatewayDevicesNode));
 | 
			
		||||
                                saveGatewayDevicesAttribute(device, relationToGateway, renamedGatewayDevicesKvEntry);
 | 
			
		||||
                            },
 | 
			
		||||
                            e -> log.error("Cannot get gateway renamed devices attribute", e));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            EntityRelation relationToGateway = relationToGatewayList.get(0);
 | 
			
		||||
            Device gatewayDevice = deviceService.findDeviceById(device.getTenantId(), (DeviceId) relationToGateway.getTo());
 | 
			
		||||
            ObjectNode renamedDeviceNode = JacksonUtil.newObjectNode();
 | 
			
		||||
            renamedDeviceNode.put(device.getName(), oldDevice.getName());
 | 
			
		||||
            ToDeviceRpcRequest rpcRequest = formDeviceToGatewayRPCRequest(gatewayDevice, renamedDeviceNode, DEVICE_RENAMED_METHOD_NAME);
 | 
			
		||||
            deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> {
 | 
			
		||||
                log.trace("Device renamed RPC with id: [{}] processed to gateway device with id: [{}], old device name: [{}], new device name: [{}]",
 | 
			
		||||
                        rpcRequest.getId(), gatewayDevice.getId(), oldDevice.getName(), device.getName());
 | 
			
		||||
            }, null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -121,94 +84,29 @@ public class DefaultGatewayDeviceStateService implements GatewayDeviceStateServi
 | 
			
		||||
        List<EntityRelation> relationToGatewayList = relationService.findByFromAndType(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.LAST_CONNECTED_GATEWAY, RelationTypeGroup.COMMON);
 | 
			
		||||
        if (!relationToGatewayList.isEmpty()) {
 | 
			
		||||
            EntityRelation relationToGateway = relationToGatewayList.get(0);
 | 
			
		||||
            final String[] deletedDeviceName = {device.getName()};
 | 
			
		||||
            ListenableFuture<List<AttributeKvEntry>> renamedGatewayDevicesFuture = attributesService.find(device.getTenantId(), relationToGateway.getTo(), DataConstants.SHARED_SCOPE, Collections.singletonList("renamedGatewayDevices"));
 | 
			
		||||
            DonAsynchron.withCallback(renamedGatewayDevicesFuture, renamedGatewayDevicesList -> {
 | 
			
		||||
                if (!renamedGatewayDevicesList.isEmpty()) {
 | 
			
		||||
                    ObjectNode renamedGatewayDevicesNode = (ObjectNode) JacksonUtil.toJsonNode(renamedGatewayDevicesList.get(0).getValueAsString());
 | 
			
		||||
                    if (renamedGatewayDevicesNode != null) {
 | 
			
		||||
                        AtomicBoolean renamedListChanged = new AtomicBoolean(false);
 | 
			
		||||
                        if (renamedGatewayDevicesNode.findValue(deletedDeviceName[0]) != null) {
 | 
			
		||||
                            renamedGatewayDevicesNode.remove(deletedDeviceName[0]);
 | 
			
		||||
                            renamedListChanged.set(true);
 | 
			
		||||
                        }
 | 
			
		||||
                        Map<String, String> renamedGatewayDevicesMap = JacksonUtil.OBJECT_MAPPER.convertValue(renamedGatewayDevicesNode, new TypeReference<>() {
 | 
			
		||||
                        });
 | 
			
		||||
                        renamedGatewayDevicesMap.forEach((key, value) -> {
 | 
			
		||||
                            // If device was renamed earlier
 | 
			
		||||
                            if (deletedDeviceName[0].equals(value)) {
 | 
			
		||||
                                renamedGatewayDevicesNode.remove(key);
 | 
			
		||||
                                deletedDeviceName[0] = key;
 | 
			
		||||
                                renamedListChanged.set(true);
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                        if (renamedListChanged.get()) {
 | 
			
		||||
                            KvEntry renamedGatewayDevicesKvEntry = new JsonDataEntry(RENAMED_GATEWAY_DEVICES, JacksonUtil.toString(renamedGatewayDevicesNode));
 | 
			
		||||
                            saveGatewayDevicesAttribute(device, relationToGateway, renamedGatewayDevicesKvEntry);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, e -> log.error("Cannot get gateway renamed devices attribute", e));
 | 
			
		||||
            ListenableFuture<List<AttributeKvEntry>> deletedGatewayDevicesFuture = attributesService.find(device.getTenantId(), relationToGateway.getTo(), DataConstants.SHARED_SCOPE, Collections.singletonList("deletedGatewayDevices"));
 | 
			
		||||
            DonAsynchron.withCallback(deletedGatewayDevicesFuture, deletedGatewayDevicesList -> {
 | 
			
		||||
                ArrayNode deletedGatewayDevicesNode;
 | 
			
		||||
                if (!deletedGatewayDevicesList.isEmpty()) {
 | 
			
		||||
                    deletedGatewayDevicesNode = (ArrayNode) JacksonUtil.toJsonNode(deletedGatewayDevicesList.get(0).getValueAsString());
 | 
			
		||||
                } else {
 | 
			
		||||
                    deletedGatewayDevicesNode = JacksonUtil.OBJECT_MAPPER.createArrayNode();
 | 
			
		||||
                }
 | 
			
		||||
                deletedGatewayDevicesNode.add(deletedDeviceName[0]);
 | 
			
		||||
                KvEntry deletedGatewayDevicesKvEntry = new JsonDataEntry(DELETED_GATEWAY_DEVICES, JacksonUtil.toString(deletedGatewayDevicesNode));
 | 
			
		||||
                saveGatewayDevicesAttribute(device, relationToGateway, deletedGatewayDevicesKvEntry);
 | 
			
		||||
            }, e -> log.error("Cannot get gateway deleted devices attribute", e));
 | 
			
		||||
            Device gatewayDevice = deviceService.findDeviceById(device.getTenantId(), (DeviceId) relationToGateway.getTo());
 | 
			
		||||
            TextNode deletedDeviceNode = new TextNode(device.getName());
 | 
			
		||||
            ToDeviceRpcRequest rpcRequest = formDeviceToGatewayRPCRequest(gatewayDevice, deletedDeviceNode, DEVICE_DELETED_METHOD_NAME);
 | 
			
		||||
            deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> {
 | 
			
		||||
                log.trace("Device deleted RPC with id: [{}] processed to gateway device with id: [{}], deleted device name: [{}]",
 | 
			
		||||
                        rpcRequest.getId(), gatewayDevice.getId(), device.getName());
 | 
			
		||||
            }, null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void checkAndUpdateDeletedGatewayDevicesAttribute(Device device) {
 | 
			
		||||
        List<EntityRelation> relationToGatewayList = relationService.findByFromAndType(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.LAST_CONNECTED_GATEWAY, RelationTypeGroup.COMMON);
 | 
			
		||||
        if (!relationToGatewayList.isEmpty()) {
 | 
			
		||||
            EntityRelation relationToGateway = relationToGatewayList.get(0);
 | 
			
		||||
            ListenableFuture<List<AttributeKvEntry>> deletedGatewayDevicesFuture = attributesService.find(device.getTenantId(), relationToGateway.getTo(), DataConstants.SHARED_SCOPE, Collections.singletonList("deletedGatewayDevices"));
 | 
			
		||||
            DonAsynchron.withCallback(deletedGatewayDevicesFuture, deletedGatewayDevicesList -> {
 | 
			
		||||
                ArrayNode deletedGatewayDevicesNode;
 | 
			
		||||
                if (!deletedGatewayDevicesList.isEmpty()) {
 | 
			
		||||
                    int deletedDeviceIndex = -1;
 | 
			
		||||
                    deletedGatewayDevicesNode = (ArrayNode) JacksonUtil.toJsonNode(deletedGatewayDevicesList.get(0).getValueAsString());
 | 
			
		||||
                    for (int i = 0; i < deletedGatewayDevicesNode.size(); i++) {
 | 
			
		||||
                        if (deletedGatewayDevicesNode.get(i).asText().equals(device.getName())) {
 | 
			
		||||
                            deletedDeviceIndex = i;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (deletedDeviceIndex != -1) {
 | 
			
		||||
                        deletedGatewayDevicesNode.remove(deletedDeviceIndex);
 | 
			
		||||
                        KvEntry deletedGatewayDevicesKvEntry = new JsonDataEntry(DELETED_GATEWAY_DEVICES, JacksonUtil.toString(deletedGatewayDevicesNode));
 | 
			
		||||
                        saveGatewayDevicesAttribute(device, relationToGateway, deletedGatewayDevicesKvEntry);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, e -> log.error("Cannot get gateway deleted devices attribute", e));
 | 
			
		||||
        }
 | 
			
		||||
    private ToDeviceRpcRequest formDeviceToGatewayRPCRequest(Device gatewayDevice, JsonNode deviceDataNode, String method) {
 | 
			
		||||
        ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(method, JacksonUtil.toString(deviceDataNode));
 | 
			
		||||
        long expTime = System.currentTimeMillis() + Math.max(minTimeout, defaultTimeout);
 | 
			
		||||
        UUID rpcRequestUUID = UUID.randomUUID();
 | 
			
		||||
        return new ToDeviceRpcRequest(rpcRequestUUID,
 | 
			
		||||
                gatewayDevice.getTenantId(),
 | 
			
		||||
                gatewayDevice.getId(),
 | 
			
		||||
                true,
 | 
			
		||||
                expTime,
 | 
			
		||||
                body,
 | 
			
		||||
                true,
 | 
			
		||||
                null,
 | 
			
		||||
                null
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveGatewayDevicesAttribute(Device device, EntityRelation relationToGateway, KvEntry gatewayDevicesKvEntry) {
 | 
			
		||||
        AttributeKvEntry attrKvEntry = new BaseAttributeKvEntry(System.currentTimeMillis(), gatewayDevicesKvEntry);
 | 
			
		||||
        tsSubService.saveAndNotify(device.getTenantId(), relationToGateway.getTo(), DataConstants.SHARED_SCOPE, List.of(attrKvEntry), true, new FutureCallback<Void>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@Nullable Void unused) {
 | 
			
		||||
                log.trace("Attribute saved for gateway with ID [{}] and data [{}]", relationToGateway.getTo(), gatewayDevicesKvEntry.getJsonValue());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(Throwable throwable) {
 | 
			
		||||
                log.error("Cannot save gateway device attribute", throwable);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isHandleDeviceRenamingEnabled(JsonNode additionalInfo) {
 | 
			
		||||
        if (additionalInfo.get(HANDLE_DEVICE_RENAMING_PARAMETER) != null) {
 | 
			
		||||
            return additionalInfo.get(HANDLE_DEVICE_RENAMING_PARAMETER).asBoolean();
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,4 @@ public interface GatewayDeviceStateService {
 | 
			
		||||
    void update(Device device, Device oldDevice);
 | 
			
		||||
 | 
			
		||||
    void delete(Device device);
 | 
			
		||||
 | 
			
		||||
    void checkAndUpdateDeletedGatewayDevicesAttribute(Device device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -401,13 +401,18 @@ public class DefaultTbClusterService implements TbClusterService {
 | 
			
		||||
    public void onDeviceUpdated(Device device, Device old, boolean notifyEdge) {
 | 
			
		||||
        var created = old == null;
 | 
			
		||||
        broadcastEntityChangeToTransport(device.getTenantId(), device.getId(), device, null);
 | 
			
		||||
        if (old != null && (!device.getName().equals(old.getName()) || !device.getType().equals(old.getType()))) {
 | 
			
		||||
            pushMsgToCore(new DeviceNameOrTypeUpdateMsg(device.getTenantId(), device.getId(), device.getName(), device.getType()), null);
 | 
			
		||||
        if (old != null) {
 | 
			
		||||
            boolean deviceNameChanged = !device.getName().equals(old.getName());
 | 
			
		||||
            if (deviceNameChanged) {
 | 
			
		||||
                gatewayDeviceStateService.update(device, old);
 | 
			
		||||
            }
 | 
			
		||||
            if (deviceNameChanged || !device.getType().equals(old.getType())) {
 | 
			
		||||
                pushMsgToCore(new DeviceNameOrTypeUpdateMsg(device.getTenantId(), device.getId(), device.getName(), device.getType()), null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        broadcastEntityStateChangeEvent(device.getTenantId(), device.getId(), created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
 | 
			
		||||
        sendDeviceStateServiceEvent(device.getTenantId(), device.getId(), created, !created, false);
 | 
			
		||||
        otaPackageStateService.update(device, old);
 | 
			
		||||
        gatewayDeviceStateService.update(device, old);
 | 
			
		||||
        if (!created && notifyEdge) {
 | 
			
		||||
            sendNotificationMsgToEdgeService(device.getTenantId(), null, device.getId(), null, null, EdgeEventActionType.UPDATED);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -22,10 +22,12 @@ import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.common.util.ThingsBoardThreadFactory;
 | 
			
		||||
import org.thingsboard.server.common.data.rpc.RpcError;
 | 
			
		||||
import org.thingsboard.server.actors.ActorSystemContext;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.common.data.DataConstants;
 | 
			
		||||
import org.thingsboard.server.common.data.Device;
 | 
			
		||||
import org.thingsboard.server.common.data.User;
 | 
			
		||||
import org.thingsboard.server.common.data.rpc.RpcError;
 | 
			
		||||
import org.thingsboard.server.common.msg.TbMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.TbMsgDataType;
 | 
			
		||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
 | 
			
		||||
@ -34,7 +36,6 @@ import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
 | 
			
		||||
import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
@ -183,7 +184,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
 | 
			
		||||
        entityNode.put(DataConstants.ADDITIONAL_INFO, msg.getAdditionalInfo());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), currentUser.getCustomerId(), metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
 | 
			
		||||
            TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), Optional.ofNullable(currentUser).map(User::getCustomerId).orElse(null), metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
 | 
			
		||||
            clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null);
 | 
			
		||||
        } catch (JsonProcessingException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
 | 
			
		||||
@ -95,11 +95,9 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
 | 
			
		||||
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
 | 
			
		||||
import org.thingsboard.server.service.gateway_device.GatewayDeviceStateService;
 | 
			
		||||
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.service.resource.TbResourceService;
 | 
			
		||||
import org.thingsboard.server.service.state.DeviceStateService;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@ -130,7 +128,6 @@ public class DefaultTransportApiService implements TransportApiService {
 | 
			
		||||
    private final DeviceService deviceService;
 | 
			
		||||
    private final RelationService relationService;
 | 
			
		||||
    private final DeviceCredentialsService deviceCredentialsService;
 | 
			
		||||
    private final DeviceStateService deviceStateService;
 | 
			
		||||
    private final DbCallbackExecutorService dbCallbackExecutorService;
 | 
			
		||||
    private final TbClusterService tbClusterService;
 | 
			
		||||
    private final DataDecodingEncodingService dataDecodingEncodingService;
 | 
			
		||||
@ -138,7 +135,6 @@ public class DefaultTransportApiService implements TransportApiService {
 | 
			
		||||
    private final TbResourceService resourceService;
 | 
			
		||||
    private final OtaPackageService otaPackageService;
 | 
			
		||||
    private final OtaPackageDataCache otaPackageDataCache;
 | 
			
		||||
    private final GatewayDeviceStateService gatewayDeviceStateService;
 | 
			
		||||
 | 
			
		||||
    private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
@ -319,8 +315,6 @@ public class DefaultTransportApiService implements TransportApiService {
 | 
			
		||||
                }
 | 
			
		||||
                relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, lastConnectedGatewayRelation);
 | 
			
		||||
 | 
			
		||||
                gatewayDeviceStateService.checkAndUpdateDeletedGatewayDevicesAttribute(device);
 | 
			
		||||
 | 
			
		||||
                GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder()
 | 
			
		||||
                        .setDeviceInfo(getDeviceInfoProto(device));
 | 
			
		||||
                DeviceProfile deviceProfile = deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId());
 | 
			
		||||
 | 
			
		||||
@ -103,16 +103,10 @@
 | 
			
		||||
              <mat-checkbox formControlName="gateway">
 | 
			
		||||
                {{ 'device.is-gateway' | translate }}
 | 
			
		||||
              </mat-checkbox>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div fxLayout="row" fxLayout.xs="column" style="padding-bottom: 16px;">
 | 
			
		||||
              <mat-checkbox *ngIf="deviceWizardFormGroup.get('gateway').value"
 | 
			
		||||
                            formControlName="overwriteActivityTime">
 | 
			
		||||
                {{ 'device.overwrite-activity-time' | translate }}
 | 
			
		||||
              </mat-checkbox>
 | 
			
		||||
              <mat-checkbox *ngIf="deviceWizardFormGroup.get('gateway').value"
 | 
			
		||||
                            formControlName="handleDeviceRenaming">
 | 
			
		||||
                {{ 'device.handle-device-renaming' | translate }}
 | 
			
		||||
              </mat-checkbox>
 | 
			
		||||
            </div>
 | 
			
		||||
            <mat-form-field class="mat-block">
 | 
			
		||||
              <mat-label translate>device.description</mat-label>
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,6 @@ export class DeviceWizardDialogComponent extends
 | 
			
		||||
        label: ['', Validators.maxLength(255)],
 | 
			
		||||
        gateway: [false],
 | 
			
		||||
        overwriteActivityTime: [false],
 | 
			
		||||
        handleDeviceRenaming: [false],
 | 
			
		||||
        addProfileType: [0],
 | 
			
		||||
        deviceProfileId: [null, Validators.required],
 | 
			
		||||
        newDeviceProfileTitle: [{value: null, disabled: true}],
 | 
			
		||||
@ -327,7 +326,6 @@ export class DeviceWizardDialogComponent extends
 | 
			
		||||
      additionalInfo: {
 | 
			
		||||
        gateway: this.deviceWizardFormGroup.get('gateway').value,
 | 
			
		||||
        overwriteActivityTime: this.deviceWizardFormGroup.get('overwriteActivityTime').value,
 | 
			
		||||
        handleDeviceRenaming: this.deviceWizardFormGroup.get('handleDeviceRenaming').value,
 | 
			
		||||
        description: this.deviceWizardFormGroup.get('description').value
 | 
			
		||||
      },
 | 
			
		||||
      customerId: null
 | 
			
		||||
 | 
			
		||||
@ -128,16 +128,10 @@
 | 
			
		||||
          <mat-checkbox fxFlex.gt-sm="30" fxFlex formControlName="gateway">
 | 
			
		||||
            {{ 'device.is-gateway' | translate }}
 | 
			
		||||
          </mat-checkbox>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div fxLayout="row" fxLayout.xs="column" style="padding-bottom: 16px;">
 | 
			
		||||
          <mat-checkbox fxFlex *ngIf="entityForm.get('additionalInfo.gateway').value"
 | 
			
		||||
                        formControlName="overwriteActivityTime">
 | 
			
		||||
            {{ 'device.overwrite-activity-time' | translate }}
 | 
			
		||||
          </mat-checkbox>
 | 
			
		||||
          <mat-checkbox *ngIf="entityForm.get('additionalInfo.gateway').value"
 | 
			
		||||
                        formControlName="handleDeviceRenaming">
 | 
			
		||||
            {{ 'device.handle-device-renaming' | translate }}
 | 
			
		||||
          </mat-checkbox>
 | 
			
		||||
        </div>
 | 
			
		||||
        <mat-form-field class="mat-block">
 | 
			
		||||
          <mat-label translate>device.description</mat-label>
 | 
			
		||||
 | 
			
		||||
@ -92,7 +92,6 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
 | 
			
		||||
          {
 | 
			
		||||
            gateway: [entity && entity.additionalInfo ? entity.additionalInfo.gateway : false],
 | 
			
		||||
            overwriteActivityTime: [entity && entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false],
 | 
			
		||||
            handleDeviceRenaming: [entity && entity.additionalInfo ? entity.additionalInfo.handleDeviceRenaming : false],
 | 
			
		||||
            description: [entity && entity.additionalInfo ? entity.additionalInfo.description : ''],
 | 
			
		||||
          }
 | 
			
		||||
        )
 | 
			
		||||
@ -122,7 +121,6 @@ export class DeviceComponent extends EntityComponent<DeviceInfo> {
 | 
			
		||||
      additionalInfo: {
 | 
			
		||||
        gateway: entity.additionalInfo ? entity.additionalInfo.gateway : false,
 | 
			
		||||
        overwriteActivityTime: entity.additionalInfo ? entity.additionalInfo.overwriteActivityTime : false,
 | 
			
		||||
        handleDeviceRenaming: entity.additionalInfo ? entity.additionalInfo.handleDeviceRenaming : false,
 | 
			
		||||
        description: entity.additionalInfo ? entity.additionalInfo.description : ''
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -1045,7 +1045,6 @@
 | 
			
		||||
        "unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}",
 | 
			
		||||
        "is-gateway": "Is gateway",
 | 
			
		||||
        "overwrite-activity-time": "Overwrite activity time for connected device",
 | 
			
		||||
        "handle-device-renaming": "Handle device renaming",
 | 
			
		||||
        "public": "Public",
 | 
			
		||||
        "device-public": "Device is public",
 | 
			
		||||
        "select-device": "Select device",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user