Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 42 additions & 40 deletions src/main/java/com/capstone/favicon/aws/S3Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,48 +38,50 @@ public S3Controller(@Qualifier("s3Config") S3Config s3Config, DatasetRepository
}

@PostMapping("/upload")
public ResponseEntity<APIResponse<String>> uploadFile(@RequestParam("file") MultipartFile file) {
public ResponseEntity<APIResponse<String>> uploadFile(@RequestParam("files") MultipartFile[] files) {
try {
if (file.isEmpty() || file.getOriginalFilename() == null || file.getOriginalFilename().trim().isEmpty()) {
return ResponseEntity.badRequest().body(APIResponse.errorAPI("파일 이름이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));
for (MultipartFile file : files) {
if (file.isEmpty() || file.getOriginalFilename() == null || file.getOriginalFilename().trim().isEmpty()) {
return ResponseEntity.badRequest().body(APIResponse.errorAPI("파일 이름이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."));
}

String originalFileName = file.getOriginalFilename().trim();
String directory = "preprocessing";
String fileUrl = s3Config.uploadFile(file, directory);

List<DatasetTheme> datasetThemes = datasetThemeRepository.findAll();
String s3FileName = directory + "/" + originalFileName;
DatasetMetadata metadata = MetadataParser.extractMetadata(s3FileName, datasetThemes);

DatasetTheme datasetTheme = datasetThemes.stream()
.filter(theme -> theme.getDatasetThemeId().equals(metadata.getDatasetThemeId()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή dataset_theme_idκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: " + metadata.getDatasetThemeId()));

Dataset dataset = datasetRepository
.findByDatasetThemeAndNameAndOrganization(datasetTheme, metadata.getName(), metadata.getOrganization())
.orElseGet(() -> {
LocalDate lastModified = s3Config.getLastModifiedDate(s3FileName);
return datasetRepository.save(new Dataset(
datasetTheme,
metadata.getName(),
metadata.getTitle(),
metadata.getOrganization(),
metadata.getDescription(),
s3FileName,
LocalDate.now(),
lastModified,
0,
0
));
});

FileExtension type = FileExtension.valueOf(metadata.getType());
Resource resource = new Resource(dataset, originalFileName, type, fileUrl);
resourceRepository.save(resource);
}

String originalFileName = file.getOriginalFilename().trim();
String directory = "preprocessing";
String fileUrl = s3Config.uploadFile(file, directory);

List<DatasetTheme> datasetThemes = datasetThemeRepository.findAll();
String s3FileName = directory + "/" + originalFileName;
DatasetMetadata metadata = MetadataParser.extractMetadata(s3FileName, datasetThemes);

DatasetTheme datasetTheme = datasetThemes.stream()
.filter(theme -> theme.getDatasetThemeId().equals(metadata.getDatasetThemeId()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή dataset_theme_idκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: " + metadata.getDatasetThemeId()));

Dataset dataset = datasetRepository
.findByDatasetThemeAndNameAndOrganization(datasetTheme, metadata.getName(), metadata.getOrganization())
.orElseGet(() -> {
LocalDate lastModified = s3Config.getLastModifiedDate(s3FileName);
return datasetRepository.save(new Dataset(
datasetTheme,
metadata.getName(),
metadata.getTitle(),
metadata.getOrganization(),
metadata.getDescription(),
s3FileName,
LocalDate.now(),
lastModified,
0,
0
));
});

FileExtension type = FileExtension.valueOf(metadata.getType());
Resource resource = new Resource(dataset, originalFileName, type, fileUrl);
resourceRepository.save(resource);

return ResponseEntity.ok(APIResponse.successAPI("파일이 μ—…λ‘œλ“œλ˜μ—ˆμŠ΅λ‹ˆλ‹€", fileUrl));
return ResponseEntity.ok(APIResponse.successAPI("파일이 μ—…λ‘œλ“œλ˜μ—ˆμŠ΅λ‹ˆλ‹€", null));

} catch (IllegalArgumentException | IOException e) {
return ResponseEntity.badRequest().body(APIResponse.errorAPI(e.getMessage()));
Expand All @@ -98,7 +100,7 @@ public ResponseEntity<APIResponse<String>> deleteFile(@PathVariable Long resourc
Dataset dataset = resource.getDataset();

s3Config.deleteFile(resource.getResourceUrl());
dataset.setResource(null); // μ—°κ²° ν•΄μ œ
dataset.setResource(null);

resourceRepository.delete(resource);
resourceRepository.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/notice/create", "/notice/list", "/notice/{noticeId}", "/notice/view/{noticeId}", "/faq/create", "/faq/{faqId}",
"/data-set/filter", "/data-set/count","/data-set/ratio", "/data-set/incrementDownload/{datasetId}", "/data-set/top9",
"/data-set/theme", "/data-set/{datasetId}", "/data-set/category/{themeId}", "/data-set/filter", "/faq/list", "/faq/{faqId}",
"/s3/upload", "/s3/delete/{resourceId}", "/analysis", "/data-set/stats", "/request/stats",
"/s3/upload", "/s3/delete/{resourceId}", "/analysis", "/data-set/stats", "/request/stats", "/request/download/{requestId}",
"/data-set", "/request/list","/request/list/{requestId}/review", "/request/{requestId}","/request/question",
"/request/question/{questionId}", "/request/answer", "/request/answer/{answerId}","/trend/**", "/data-set/search-sorted", "/data-set/search-sorted/{category}",
"/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/data-set/download/{datasetId}", "/data-set/group-by-theme", "/region").permitAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.capstone.favicon.dataset.application.service.ResourceService;
import com.capstone.favicon.dataset.application.service.S3FileDownloadService;
import com.capstone.favicon.dataset.domain.FileExtension;
import com.capstone.favicon.user.application.service.RequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
Expand All @@ -22,6 +23,8 @@ public class S3FileDownloadServiceImpl extends S3Config implements S3FileDownloa
private ResourceService resourceService;
@Autowired
private FilePathService filePathService;
@Autowired
private RequestService requestService;

@Value("${aws.s3.bucket-name}")
private String bucketName;
Expand Down Expand Up @@ -88,4 +91,37 @@ private File createFileWithExtension(String directory, String fileName, FileExte
// String encodedFileName = encodeFileName(fileName);
return new File(downloadDir, fileName + "." + extension.name().toLowerCase());
}



public File downloadFileFromDataRequest(Long dataRequestId) throws IOException {
String downloadDir = filePathService.getDownloadDir();

String fileUrl = requestService.getFileUrlByRequestId(dataRequestId);
FileExtension fileExtension = requestService.getFileExtensionByRequestId(dataRequestId);

String key = extractKeyFromUrl(fileUrl);
String fileName = extractFileNameFromKey(key);
String encodedFileName = encodeFileName(fileName);
File file = createFileWithExtension(downloadDir, encodedFileName, fileExtension);

GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();

try (ResponseInputStream<GetObjectResponse> s3Object = s3Client.getObject(getObjectRequest);
FileOutputStream fos = new FileOutputStream(file)) {
byte[] buffer = new byte[1024];
int length;
while ((length = s3Object.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
}

return file;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

public interface S3FileDownloadService {
File downloadFile(Long datasetId) throws IOException;

File downloadFileFromDataRequest(Long dataRequestId) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;

@RestController
@RequestMapping("/data-set")
Expand All @@ -21,16 +22,16 @@ public class s3FileDownloadController {
@Autowired
private S3FileDownloadService s3FileDownloadService;

@GetMapping(value="/download/{datasetId}", produces = "application/json; charset=UTF-8")
public ResponseEntity<APIResponse<?>> downloadFile(@PathVariable Long datasetId) throws IOException {

@GetMapping("/download/{datasetId}")
public ResponseEntity<Resource> downloadFile(@PathVariable Long datasetId) throws IOException {
File downloadedFile = s3FileDownloadService.downloadFile(datasetId);
Resource fileResource = new FileSystemResource(downloadedFile);
String fileName = downloadedFile.getName();

return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8" + fileName)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(APIResponse.successAPI("success", fileResource));
.body(fileResource);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.capstone.favicon.user.application;

import com.capstone.favicon.config.S3Config;
import com.capstone.favicon.dataset.domain.FileExtension;
import com.capstone.favicon.user.domain.DataRequest;
import com.capstone.favicon.user.domain.Question;
import com.capstone.favicon.user.domain.Answer;
Expand Down Expand Up @@ -113,7 +114,6 @@ public List<Answer> getAnswersByQuestion(Long questionId) {
return answerRepository.findByQuestion_User_UserId(questionId);
}

// --- ✨ μΆ”κ°€ κΈ°λŠ₯λ“€ ---

@Override
@Transactional
Expand Down Expand Up @@ -241,4 +241,27 @@ public RequestStatsDto getRequestStats() {
);
}




@Override
public String getFileUrlByRequestId(Long requestId) {
DataRequest dataRequest = dataRequestRepository.findById(requestId)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή ID의 μš”μ²­μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: " + requestId));
return dataRequest.getFileUrl();
}

@Override
public FileExtension getFileExtensionByRequestId(Long requestId) {
DataRequest dataRequest = dataRequestRepository.findById(requestId)
.orElseThrow(() -> new IllegalArgumentException("ν•΄λ‹Ή ID의 μš”μ²­μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: " + requestId));
return extractExtension(dataRequest.getFileUrl());
}

private FileExtension extractExtension(String fileUrl) {
String ext = fileUrl.substring(fileUrl.lastIndexOf('.') + 1).toUpperCase();
return FileExtension.valueOf(ext);
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.capstone.favicon.user.application.service;

import com.capstone.favicon.dataset.domain.FileExtension;
import com.capstone.favicon.user.domain.DataRequest;
import com.capstone.favicon.user.domain.Question;
import com.capstone.favicon.user.domain.Answer;
Expand All @@ -26,4 +27,8 @@ public interface RequestService {
Answer createAnswer(Answer answer);
Answer updateAnswer(Long answerId, Answer updatedAnswer);
void deleteAnswer(Long answerId);


String getFileUrlByRequestId(Long requestId);
FileExtension getFileExtensionByRequestId(Long requestId);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package com.capstone.favicon.user.controller;

import com.capstone.favicon.config.APIResponse;
import com.capstone.favicon.dataset.application.service.S3FileDownloadService;
import org.springframework.core.io.Resource;
import com.capstone.favicon.user.domain.DataRequest;
import com.capstone.favicon.user.dto.DataRequestDto;
import com.capstone.favicon.user.domain.Question;
import com.capstone.favicon.user.domain.Answer;
import com.capstone.favicon.user.application.service.RequestService;
import com.capstone.favicon.user.dto.RequestStatsDto;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;

@RestController
Expand Down Expand Up @@ -168,4 +175,26 @@ public ResponseEntity<APIResponse<?>> deleteAnswer(@PathVariable Long answerId)
}
}



@Autowired
private S3FileDownloadService s3FileDownloadService;

@GetMapping("/download/{requestId}")
public ResponseEntity<Resource> downloadDataRequestFile(@PathVariable Long requestId) throws IOException {
File downloadedFile = s3FileDownloadService.downloadFileFromDataRequest(requestId);
Resource fileResource = new FileSystemResource(downloadedFile);
String fileName = downloadedFile.getName();

return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + fileName)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(fileResource);
}






}
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spring.mail.password=${SPRING_MAIL_PASSWORD}
spring.mail.properties.mail.smtp.auth=ture
spring.mail.properties.mail.smtp.starttls.required=true

spring.data.redis.host=redis
spring.data.redis.host=${REDIS_HOST}
spring.data.redis.port=6379

# AWS
Expand Down
Loading