package im.rosetta.service.dispatch; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import im.rosetta.client.ClientManager; import im.rosetta.client.tags.ECIDevice; import im.rosetta.database.entity.Device; import im.rosetta.database.repository.DeviceRepository; import im.rosetta.network.enums.DeviceSolution; import im.rosetta.network.enums.NetworkStatus; import im.rosetta.network.packet.PacketDeviceList; import im.rosetta.network.types.NetworkDevice; import im.rosetta.service.services.DeviceService; import io.orprotocol.ProtocolException; import io.orprotocol.client.Client; /** * Диспетчер устройств, который отвечает за списки устройств в аккаунте */ public class DeviceDispatcher { private ClientManager clientManager; private DeviceRepository deviceRepository = new DeviceRepository(); private DeviceService deviceService = new DeviceService(deviceRepository); public DeviceDispatcher(ClientManager clientManager) { this.clientManager = clientManager; } /** * Отправит список подключенных устройств всем авторизованным устройствам с publicKey * @param publicKey публичный ключ аккаунта, для которого нужно отправить список устройств */ public void sendDevices(String publicKey) throws ProtocolException { /** * Получаем список авторизованных устройств, а так же список устройств которые сейчас в сети */ List verifiedDevices = deviceService.getDevicesByPK(publicKey); List onlineDevices = this.getOnlineDevices(publicKey); Map byId = new HashMap<>(); /** * Верифицированные устройства, по умолчанию оффлайн, но верифицированные */ for (Device d : verifiedDevices) { String id = d.getDeviceId(); NetworkDevice nd = new NetworkDevice(); nd.setDeviceId(id); nd.setDeviceSolution(DeviceSolution.ACCEPT); nd.setNetworkStatus(NetworkStatus.OFFLINE); nd.setDeviceName(d.getDeviceName()); nd.setDeviceOs(d.getDeviceOs()); byId.put(id, nd); } /** * Подгоняем онлайн статус, если усотройство верифицированно, то оно найдется * в Map, если устройства там нет соотвественно оно не верифицированно */ for (ECIDevice od : onlineDevices) { String id = od.getDeviceId(); NetworkDevice nd = byId.get(id); if (nd == null) { nd = new NetworkDevice(); nd.setDeviceId(id); nd.setDeviceSolution(DeviceSolution.DECLINE); nd.setDeviceName(od.getDeviceName()); nd.setDeviceOs(od.getDeviceOs()); byId.put(id, nd); } nd.setNetworkStatus(NetworkStatus.ONLINE); } List networkDevices = new ArrayList<>(byId.values()); PacketDeviceList packet = new PacketDeviceList(); packet.setDevices(networkDevices); this.clientManager.sendPacketToAuthorizedPK(publicKey, packet); } /** * Получить список устройств которые сейчас в сети для публичного ключа (берутся и не авторизованные устройства, так как они тоже в сети) * @param publicKey публичный ключ аккаунта, для которого нужно получить список устройств которые сейчас в сети * @return список устройств которые сейчас в сети для публичного ключа */ private List getOnlineDevices(String publicKey) { List onlineDevices = new java.util.ArrayList<>(); List clients = clientManager.getPKClients(publicKey); for(Client client : clients){ ECIDevice deviceTag = client.getTag(ECIDevice.class); if(deviceTag != null){ onlineDevices.add(deviceTag); } } return onlineDevices; } }