Update downloadFile

This commit is contained in:
2025-07-10 17:17:53 +02:00
parent ab3f9369b0
commit 08e8dcf1a6
4 changed files with 93 additions and 73 deletions

View File

@@ -7,23 +7,18 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.netflix.discovery.converters.Auto;
import com.olympus.dto.FileUploadDTO;
import com.olympus.hermione.dto.FileDeleteRequest; import com.olympus.hermione.dto.FileDeleteRequest;
import com.olympus.hermione.services.FileService; import com.olympus.hermione.services.FileService;
import com.olympus.model.apollo.KSDocument;
import com.olympus.model.apollo.KSIngestionInfo;
@RestController @RestController
public class FileController { public class FileController {
@@ -44,4 +39,12 @@ public class FileController {
public ResponseEntity<String> deleteFile(@RequestBody FileDeleteRequest request) { public ResponseEntity<String> deleteFile(@RequestBody FileDeleteRequest request) {
return fileService.deleteFile(request); return fileService.deleteFile(request);
} }
@GetMapping("/downloadFile")
public ResponseEntity<Resource> downloadFile(
@RequestParam("filePath") String filePath,
@RequestParam("executionId") String executionId) {
return fileService.downloadFile(filePath, executionId);
}
} }

View File

@@ -1,46 +0,0 @@
package com.olympus.hermione.controllers.dashboard;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.olympus.hermione.repository.dashboard.DashboardChatModel;
import com.olympus.hermione.repository.dashboard.DashboardScenarioChatRepository;
@RestController
public class DashboardChatController {
/*@Autowired
private DashboardScenarioChatRepository scenarioTestChatRepository;
// Recupera tutti i messaggi
@GetMapping("/chat/all")
public List<DashboardChatModel> getAllMessages() {
return scenarioTestChatRepository.findAll();
}
// Filtra per userId
@GetMapping("/chat/byUser")
public List<DashboardChatModel> getByUserId(@RequestParam String userId) {
return scenarioTestChatRepository.findByUserId(userId);
}
// Filtra per conversationId
@GetMapping("/chat/byConversation")
public List<DashboardChatModel> getByConversationId(@RequestParam String conversationId) {
return scenarioTestChatRepository.findByConversationId(conversationId);
}
// Filtra per scenarioId
@GetMapping("/chat/byScenario")
public List<DashboardChatModel> getByScenarioId(@RequestParam String scenarioId) {
return scenarioTestChatRepository.findByScenarioId(scenarioId);
}
@PostMapping("/save")
public DashboardChatModel saveMessage(@RequestBody DashboardChatModel message) { //salva i nuovi messaggi
return scenarioTestChatRepository.save(message);
}
*/
}

View File

@@ -2,28 +2,24 @@ package com.olympus.hermione.services;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.File; import java.io.File;
import java.text.SimpleDateFormat; import java.io.IOException;
import java.util.HashMap; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Random;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.olympus.dto.FileUploadDTO;
import com.olympus.hermione.dto.FileDeleteRequest; import com.olympus.hermione.dto.FileDeleteRequest;
import com.olympus.model.apollo.KSDocument;
import com.olympus.model.apollo.KSIngestionInfo;
@Service @Service
public class FileService { public class FileService {
@@ -147,4 +143,78 @@ public class FileService {
return null; return null;
} }
/**
* Scarica un file dal path specificato
*
* @param filePath Il path relativo del file da scaricare
* @param executionId L'ID dell'esecuzione per il logging
* @return ResponseEntity con il file come Resource
*/
public ResponseEntity<Resource> downloadFile(String filePath, String executionId) {
try {
logger.info("Downloading file: {} for execution: {}", filePath, executionId);
// Normalizza il path rimuovendo eventuali separatori doppi o tripli
String normalizedPath = filePath.replaceAll("[\\\\/]+", "/");
// Costruisci il path completo del file
Path file = Paths.get(uploadDir, normalizedPath);
logger.info("Upload directory: {}", uploadDir);
logger.info("Normalized relative path: {}", normalizedPath);
logger.info("Full file path: {}", file.toAbsolutePath());
// Verifica che il file esista e sia leggibile
if (!Files.exists(file)) {
logger.error("File not found: {}", file.toAbsolutePath());
return ResponseEntity.notFound().build();
}
if (!Files.isReadable(file)) {
logger.error("File not readable: {}", file.toAbsolutePath());
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// Verifica che il file sia all'interno della directory di upload (security check)
Path uploadPath = Paths.get(uploadDir).toAbsolutePath().normalize();
Path filePath_abs = file.toAbsolutePath().normalize();
if (!filePath_abs.startsWith(uploadPath)) {
logger.error("Security violation: attempting to access file outside upload directory: {}", filePath_abs);
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// Crea la risorsa file
Resource resource = new FileSystemResource(file);
// Determina il content type
String contentType = Files.probeContentType(file);
if (contentType == null) {
contentType = "application/octet-stream";
}
// Estrai il nome del file
String fileName = file.getFileName().toString();
// Costruisci gli header per il download
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
headers.add(HttpHeaders.CONTENT_TYPE, contentType);
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(resource.contentLength()));
logger.info("File downloaded successfully: {} (size: {} bytes)", fileName, resource.contentLength());
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.parseMediaType(contentType))
.body(resource);
} catch (IOException e) {
logger.error("Error downloading file: {} - {}", filePath, e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} catch (Exception e) {
logger.error("Unexpected error downloading file: {} - {}", filePath, e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
} }

View File

@@ -331,16 +331,9 @@ public class ScenarioExecutionService {
scenarioExecution.setScenario(scenario); scenarioExecution.setScenario(scenario);
// prendi i file dalla cartella temporanea se è presente una chiave con name // prendi i file dalla cartella temporanea se è presente una chiave con name
// "MultiFileUpload" // "MultiFileUpload"
if (scenarioExecutionInput.getInputs().containsKey("MultiFileUpload")) { if (scenarioExecutionInput.getInputs().containsKey("MultiFileUpload")) {
folder_name = scenarioExecutionInput.getInputs().get("MultiFileUpload"); folder_name = scenarioExecutionInput.getInputs().get("MultiFileUpload");
if (folder_name != null && !folder_name.equals("")) {
try {
String base64 = folderToBase64(folder_name);
scenarioExecutionInput.getInputs().put("MultiFileUpload", base64);
} catch (Exception e) {
logger.error("Error while converting folder to base64: " + e.getMessage());
}
}
} }
if (scenarioExecutionInput.getInputs().containsKey("SingleFileUpload")) { if (scenarioExecutionInput.getInputs().containsKey("SingleFileUpload")) {
scenarioExecutionInput.getInputs().put("SingleFileUpload", scenarioExecutionInput.getInputs().put("SingleFileUpload",