diff --git a/build.gradle b/build.gradle index 4d7fcbc2..87a1f1b7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,56 +1,57 @@ plugins { - id 'java-library' - id 'org.springframework.boot' version '2.7.13' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'java-library' + id 'org.springframework.boot' version '2.7.13' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' } allprojects { - group = 'likelion.univ' - version = '0.0.1-SNAPSHOT' + group = 'likelion.univ' + version = '0.0.1-SNAPSHOT' - java { - sourceCompatibility = 17 - targetCompatibility = 17 - } - repositories { - mavenCentral() - } - dependencies { + java { + sourceCompatibility = 17 + targetCompatibility = 17 + } + repositories { + mavenCentral() + } + dependencies { // implementation 'org.springframework.boot:spring-boot-starter' // annotationProcessor('org.springframework.boot:spring-boot-configuration-processor:3.0.4') - } + } } repositories { - mavenCentral() + mavenCentral() } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } /* subprojects의 내용은 하위 모듈에 모두 적용하는 설정 */ subprojects { - apply plugin: 'java' - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' + apply plugin: 'java' + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' - configurations { - compileOnly { - extendsFrom annotationProcessor - } - } - dependencies { - implementation 'org.springframework.boot:spring-boot-starter' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") - } - test { - useJUnitPlatform() - } + configurations { + compileOnly { + extendsFrom annotationProcessor + } + } + dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + } + test { + useJUnitPlatform() + } } bootJar { - enabled = false + enabled = false } diff --git a/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java b/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java index afa039de..33a483a8 100644 --- a/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java +++ b/likelion-client/src/main/java/likelion/univ/hackathon/controller/HackathonController.java @@ -1,7 +1,5 @@ package likelion.univ.hackathon.controller; -import static likelion.univ.email.ContentsType.HTML; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; @@ -18,9 +16,9 @@ import likelion.univ.utils.AuthenticatedUserUtils; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -42,12 +40,14 @@ public SuccessResponse apply( ) { Long userId = userUtils.getCurrentUserId(); Long projectId = hackathonService.apply(request.toCommand(userId)); - emailSender.send(EmailContent.builder() + EmailContent emailContent = EmailContent.builder() .subject("[멋쟁이사자처럼] 12기 중앙 해커톤 신청이 완료되었습니다.") - .contentsType(HTML.name()) .contents(HackathonApplyEmailContent.VALUE) .receivers(List.of(request.email())) - .build()); +// .attachments(List.of(FileUploadUtil.convertPngToMultipartFile(IMAGE_PATH))) + .build(); + + emailSender.send(emailContent); return SuccessResponse.of(projectId); } @@ -70,7 +70,7 @@ public SuccessResponse find( } @Operation(summary = "해커톤 신청 수정") - @PutMapping("/{hackathonFormId}") + @PatchMapping("/{hackathonFormId}") public SuccessResponse modify( @Valid @RequestBody HackathonModifyRequest request, @PathVariable("hackathonFormId") Long hackathonFormId diff --git a/likelion-client/src/main/java/likelion/univ/hackathon/email/HackathonApplyEmailContent.java b/likelion-client/src/main/java/likelion/univ/hackathon/email/HackathonApplyEmailContent.java index 2b18bbdf..e5af1763 100644 --- a/likelion-client/src/main/java/likelion/univ/hackathon/email/HackathonApplyEmailContent.java +++ b/likelion-client/src/main/java/likelion/univ/hackathon/email/HackathonApplyEmailContent.java @@ -16,7 +16,7 @@ public final class HackathonApplyEmailContent { - + @@ -48,4 +48,6 @@ public final class HackathonApplyEmailContent { """; + + public static String IMAGE_PATH = "attachment/hackathon/12th_hackathon.png"; } diff --git a/likelion-infrastructure/build.gradle b/likelion-infrastructure/build.gradle index c654f165..2f9df1e0 100644 --- a/likelion-infrastructure/build.gradle +++ b/likelion-infrastructure/build.gradle @@ -3,7 +3,6 @@ plugins { } - dependencies { /* Feign client */ implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:3.1.8' @@ -21,7 +20,7 @@ dependencies { implementation 'com.amazonaws:aws-java-sdk-s3control:1.12.428' /* azure communication (email) */ implementation group: 'com.azure', name: 'azure-communication-email', version: '1.0.2' - + implementation 'commons-fileupload:commons-fileupload:1.4' /* common 모듈 추가 */ implementation project(':likelion-common') diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/CanNotReadAttachmentException.java b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/CanNotReadAttachmentException.java new file mode 100644 index 00000000..bc0d4c27 --- /dev/null +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/CanNotReadAttachmentException.java @@ -0,0 +1,9 @@ +package likelion.univ.email.exception; + +import likelion.univ.exception.base.BaseException; + +public class CanNotReadAttachmentException extends BaseException { + public CanNotReadAttachmentException() { + super(EmailErrorCode.CAN_NOT_READ_ATTACHMENT); + } +} diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java index cbc6d234..0175000c 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/exception/EmailErrorCode.java @@ -11,7 +11,8 @@ public enum EmailErrorCode implements BaseErrorCode { EMAIL_SEND_FAILED(BAD_REQUEST, "EMAIL_400", "이메일 전송에 실패하였습니다."), - INVALID_ATTACHMENT(BAD_REQUEST, "EMAIL_401", "올바르지 않은 이메일 첨부파일 입니다."); + INVALID_ATTACHMENT(BAD_REQUEST, "EMAIL_401", "올바르지 않은 이메일 첨부파일 입니다."), + CAN_NOT_READ_ATTACHMENT(BAD_REQUEST, "EMAIL_500", "첨부파일을 읽어들이는데 실패했습니다."); private final int httpStatus; private final String code; diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java index c3e13b39..b4eaa79a 100644 --- a/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/sender/azure/AzureEmailSender.java @@ -11,6 +11,7 @@ import com.azure.core.util.BinaryData; import com.azure.core.util.polling.PollResponse; import com.azure.core.util.polling.SyncPoller; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; import likelion.univ.email.exception.EmailSendFailed; @@ -62,7 +63,12 @@ private EmailMessage createEmailMessage(EmailContent emailContent) { private void sendEmail(EmailClient emailClient, EmailMessage message) { SyncPoller poller = emailClient.beginSend(message, null); PollResponse response = poller.waitForCompletion(); - + ObjectMapper objectMapper = new ObjectMapper(); + try { + System.out.println(objectMapper.writeValueAsString(response)); + } catch (Exception e) { + System.out.println(e.getMessage()); + } if (!response.getValue().getStatus().equals(EmailSendStatus.SUCCEEDED)) { throw new EmailSendFailed(); } diff --git a/likelion-infrastructure/src/main/java/likelion/univ/email/util/FileUploadUtil.java b/likelion-infrastructure/src/main/java/likelion/univ/email/util/FileUploadUtil.java new file mode 100644 index 00000000..c5023d72 --- /dev/null +++ b/likelion-infrastructure/src/main/java/likelion/univ/email/util/FileUploadUtil.java @@ -0,0 +1,49 @@ +package likelion.univ.email.util; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import likelion.univ.email.exception.CanNotReadAttachmentException; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +public class FileUploadUtil { + + public static MultipartFile convertPngToMultipartFile(String filePath) { + Resource resource = new ClassPathResource(filePath); + + try { + InputStream inputStream = resource.getInputStream(); + FileItem fileItem = new DiskFileItem( + resource.getFilename(), + "image/png", + false, + resource.getFilename(), + (int) resource.contentLength(), + new File(System.getProperty("java.io.tmpdir")) + ); + + try (OutputStream os = fileItem.getOutputStream()) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } finally { + inputStream.close(); + } + + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + + return multipartFile; + } catch (IOException e) { + throw new CanNotReadAttachmentException(); + } + } + +} diff --git a/likelion-infrastructure/src/main/resources/attachment/hackathon/12th_hackathon.png b/likelion-infrastructure/src/main/resources/attachment/hackathon/12th_hackathon.png new file mode 100644 index 00000000..f72403cf Binary files /dev/null and b/likelion-infrastructure/src/main/resources/attachment/hackathon/12th_hackathon.png differ diff --git a/likelion-security/build.gradle b/likelion-security/build.gradle index 8d98273e..70dfca4b 100644 --- a/likelion-security/build.gradle +++ b/likelion-security/build.gradle @@ -10,13 +10,12 @@ repositories { } dependencies { - api 'org.springframework.boot:spring-boot-starter-web' /* security */ api("org.springframework.boot:spring-boot-starter-security") /* jwt */ - implementation ("io.jsonwebtoken:jjwt-api:0.11.5") - runtimeOnly ( "io.jsonwebtoken:jjwt-impl:0.11.5") - runtimeOnly ( "io.jsonwebtoken:jjwt-jackson:0.11.5") + implementation("io.jsonwebtoken:jjwt-api:0.11.5") + runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5") + runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5") /* jackson */ implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.5' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.5'