package com.sshmanager.service; import com.sshmanager.dto.BackupConnectionDto; import com.sshmanager.dto.BackupImportResponseDto; import com.sshmanager.dto.BackupPackageDto; import com.sshmanager.dto.ConnectionCreateRequest; import com.sshmanager.dto.ConnectionDto; import com.sshmanager.dto.SessionTreeLayoutDto; import com.sshmanager.dto.SessionTreeNodeDto; import com.sshmanager.entity.Connection; import com.sshmanager.repository.ConnectionRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class BackupService { private final ConnectionRepository connectionRepository; private final ConnectionService connectionService; private final SessionTreeLayoutService sessionTreeLayoutService; public BackupService(ConnectionRepository connectionRepository, ConnectionService connectionService, SessionTreeLayoutService sessionTreeLayoutService) { this.connectionRepository = connectionRepository; this.connectionService = connectionService; this.sessionTreeLayoutService = sessionTreeLayoutService; } @Transactional(readOnly = true) public BackupPackageDto exportBackup(Long userId) { BackupPackageDto backup = new BackupPackageDto(); backup.setExportedAt(Instant.now()); List exportedConnections = new ArrayList(); for (Connection connection : connectionRepository.findByUserIdOrderByUpdatedAtDesc(userId)) { BackupConnectionDto item = new BackupConnectionDto(); item.setSourceId(connection.getId()); item.setName(connection.getName()); item.setHost(connection.getHost()); item.setPort(connection.getPort()); item.setUsername(connection.getUsername()); item.setAuthType(connection.getAuthType()); item.setPassword(connectionService.getDecryptedPassword(connection)); item.setPrivateKey(connectionService.getDecryptedPrivateKey(connection)); item.setPassphrase(connectionService.getDecryptedPassphrase(connection)); exportedConnections.add(item); } backup.setConnections(exportedConnections); backup.setSessionTree(sessionTreeLayoutService.getLayout(userId)); return backup; } @Transactional @SuppressWarnings("null") public BackupImportResponseDto importBackup(Long userId, BackupPackageDto backupPackage) { if (backupPackage == null) { throw new IllegalArgumentException("Backup package is required"); } List connections = backupPackage.getConnections() == null ? new ArrayList() : backupPackage.getConnections(); SessionTreeLayoutDto sessionTree = backupPackage.getSessionTree() == null ? new SessionTreeLayoutDto() : backupPackage.getSessionTree(); connectionRepository.deleteAll(connectionRepository.findByUserIdOrderByUpdatedAtDesc(userId)); Map connectionIdMapping = new HashMap(); for (BackupConnectionDto item : connections) { ConnectionCreateRequest request = new ConnectionCreateRequest(); request.setName(item.getName()); request.setHost(item.getHost()); request.setPort(item.getPort()); request.setUsername(item.getUsername()); request.setAuthType(item.getAuthType()); request.setPassword(item.getPassword()); request.setPrivateKey(item.getPrivateKey()); request.setPassphrase(item.getPassphrase()); ConnectionDto created = connectionService.create(request, userId); if (item.getSourceId() != null) { connectionIdMapping.put(item.getSourceId(), created.getId()); } } SessionTreeLayoutDto remappedLayout = remapSessionTree(sessionTree, connectionIdMapping); sessionTreeLayoutService.saveLayout(userId, remappedLayout); int nodeCount = remappedLayout.getNodes() == null ? 0 : remappedLayout.getNodes().size(); return new BackupImportResponseDto(connections.size(), nodeCount); } private SessionTreeLayoutDto remapSessionTree(SessionTreeLayoutDto source, Map connectionIdMapping) { SessionTreeLayoutDto target = new SessionTreeLayoutDto(); target.setSortMode(source.getSortMode()); List remappedNodes = new ArrayList(); if (source.getNodes() != null) { for (SessionTreeNodeDto node : source.getNodes()) { if (node == null) { continue; } if ("connection".equals(node.getType())) { Long mappedConnectionId = connectionIdMapping.get(node.getConnectionId()); if (mappedConnectionId == null) { continue; } remappedNodes.add(new SessionTreeNodeDto( node.getId(), node.getType(), node.getName(), node.getParentId(), node.getOrder(), mappedConnectionId, node.getExpanded(), node.getCreatedAt(), node.getUpdatedAt() )); continue; } remappedNodes.add(new SessionTreeNodeDto( node.getId(), node.getType(), node.getName(), node.getParentId(), node.getOrder(), null, node.getExpanded(), node.getCreatedAt(), node.getUpdatedAt() )); } } target.setNodes(remappedNodes); return target; } }