From bf4bf5014c4727ab9e60ce9058099c6effe5a380 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Tue, 12 Jul 2022 02:08:26 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=84=9C=20=EB=B6=80=EB=B6=84=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이력서 수정부분 개발 중 ResumeService save 부분 수상내역은 완료 교육, 경력 부분 추가 개발 필요 수상, 경력 부분 resumeId 통한 해당 findAll() 메소드 필요 => 추가로 N+1 문제 발생할 수 있다. fetch join 으로 해결해야함. --- .../user/controller/CategoryController.java | 5 +- .../user/controller/ResumeController.java | 51 +++++++++---------- .../devit/user/controller/UserController.java | 5 +- .../com/devit/user/dto/EditResumeRequest.java | 2 + .../java/com/devit/user/entity/Award.java | 4 ++ .../user/repository/EducationRepository.java | 29 +++++++++++ .../com/devit/user/service/ResumeService.java | 16 ++++-- 7 files changed, 80 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/devit/user/repository/EducationRepository.java diff --git a/src/main/java/com/devit/user/controller/CategoryController.java b/src/main/java/com/devit/user/controller/CategoryController.java index d755a5a..4c5ea8c 100644 --- a/src/main/java/com/devit/user/controller/CategoryController.java +++ b/src/main/java/com/devit/user/controller/CategoryController.java @@ -6,6 +6,7 @@ import com.devit.user.entity.Category; import com.devit.user.exception.NoResourceException; import com.devit.user.service.CategoryService; +import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -19,7 +20,6 @@ * 1. 부모 카테고리 등록 * 2. 자식 카테고리 등록 * 3. 자식 카테고리들 조회 - * 4. 특정 카테고리 객체 조회 */ @RestController @RequiredArgsConstructor @@ -27,6 +27,7 @@ public class CategoryController { private final CategoryService categoryService; @PostMapping("api/users/categories/parent") //1 + @ApiOperation(value = "부모 카테고리 등록", notes = "부모 카테고리를 등록합니다.") public ResponseEntity saveParentCategory(@RequestBody CreateParentCategoryRequest request) throws NoResourceException { Category category = new Category(); category.setName(request.getName()); @@ -38,6 +39,7 @@ public ResponseEntity saveParentCategory(@RequestBody CreateParentCategoryReq } @PostMapping("api/users/categories/children") //2 + @ApiOperation(value = "자식 카테고리 등록", notes = "자식 카테고리를 등록합니다.") public ResponseEntity saveChildCategory(@RequestBody CreateChildCategoryRequest request) throws NoResourceException { Category findParent = categoryService.findCategoryByName(request.getParentName()); @@ -53,6 +55,7 @@ public ResponseEntity saveChildCategory(@RequestBody CreateChildCategoryReque } @GetMapping("api/users/categories") //3 + @ApiOperation(value = "카테고리 조회", notes = "자식 카테고리를 조회합니다.") public ResponseEntity getCategories() { List findParents = categoryService.findParentCategoires(); diff --git a/src/main/java/com/devit/user/controller/ResumeController.java b/src/main/java/com/devit/user/controller/ResumeController.java index 72a8d4c..f5c0f7f 100644 --- a/src/main/java/com/devit/user/controller/ResumeController.java +++ b/src/main/java/com/devit/user/controller/ResumeController.java @@ -9,14 +9,12 @@ import com.devit.user.service.ResumeService; import com.devit.user.service.UserService; import com.devit.user.util.HttpStatusChangeInt; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import javax.validation.constraints.Null; @@ -39,27 +37,28 @@ public class ResumeController { private final CategoryService categoryService; private final UserService userService; -// @PostMapping("/api/users/resumes") -// public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { -// -// String[] chunks = data.split("\\."); -// Base64.Decoder decoder = Base64.getDecoder(); -// String payload = new String(decoder.decode(chunks[1])); -// -// JSONObject jsonObject = new JSONObject(payload); -// String sample = jsonObject.getString("uuid"); -// UUID uuid = UUID.fromString(sample); -// -// User findUser = userService.findUser(uuid); -// -//// request.getEducations().stream() -//// .filter(e->e!=null) -//// .map(e->{Education.createEducation(e.)}) -// -// Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 -// -// int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); -// String path = "api/users/resumes"; -// } + @PutMapping("/api/users/resumes") + @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") + public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { + + String[] chunks = data.split("\\."); + Base64.Decoder decoder = Base64.getDecoder(); + String payload = new String(decoder.decode(chunks[1])); + + JSONObject jsonObject = new JSONObject(payload); + String sample = jsonObject.getString("uuid"); + UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 + + User findUser = userService.findUser(uuid); + +// request.getEducations().stream() +// .filter(e->e!=null) +// .map(e->{Education.createEducation(e.)}) + + Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 + + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); + String path = "api/users/resumes"; + } } diff --git a/src/main/java/com/devit/user/controller/UserController.java b/src/main/java/com/devit/user/controller/UserController.java index 16b154b..cd8fd27 100644 --- a/src/main/java/com/devit/user/controller/UserController.java +++ b/src/main/java/com/devit/user/controller/UserController.java @@ -30,8 +30,9 @@ public class UserController { private final UserService userService; private final ResumeService resumeService; - /* - 토큰 파싱해야함. + + /** + * 1. 유저 프로필 조회 */ @GetMapping("/api/users") diff --git a/src/main/java/com/devit/user/dto/EditResumeRequest.java b/src/main/java/com/devit/user/dto/EditResumeRequest.java index 27324c5..a84c899 100644 --- a/src/main/java/com/devit/user/dto/EditResumeRequest.java +++ b/src/main/java/com/devit/user/dto/EditResumeRequest.java @@ -1,6 +1,7 @@ package com.devit.user.dto; import com.devit.user.entity.*; +import lombok.AllArgsConstructor; import lombok.Data; import javax.persistence.*; @@ -9,6 +10,7 @@ import java.util.List; @Data +@AllArgsConstructor public class EditResumeRequest { @NotNull private Gender gender; //성별 diff --git a/src/main/java/com/devit/user/entity/Award.java b/src/main/java/com/devit/user/entity/Award.java index c1deaf2..a7e27fc 100644 --- a/src/main/java/com/devit/user/entity/Award.java +++ b/src/main/java/com/devit/user/entity/Award.java @@ -1,5 +1,7 @@ package com.devit.user.entity; +import lombok.Getter; +import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -7,6 +9,7 @@ import java.util.UUID; @Entity +@Getter @Setter public class Award { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -40,6 +43,7 @@ public class Award { private String content; //추가 자기소개 + /* 생성 메서드 */ public static Award createAward(Resume resume, LocalDate startDate, LocalDate endDate, Status awardStatus , String competition, String awards, String content) { diff --git a/src/main/java/com/devit/user/repository/EducationRepository.java b/src/main/java/com/devit/user/repository/EducationRepository.java new file mode 100644 index 0000000..500e9d2 --- /dev/null +++ b/src/main/java/com/devit/user/repository/EducationRepository.java @@ -0,0 +1,29 @@ +package com.devit.user.repository; + +import com.devit.user.entity.Award; +import com.devit.user.entity.Education; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import javax.persistence.EntityManager; +import java.util.List; +import java.util.UUID; + +@Repository +@RequiredArgsConstructor +public class EducationRepository { + private final EntityManager em; + + public Education save(Education education) { + em.persist(education); + return education; + } + + public List findAll(UUID resumeID) { + List findEducations = em.createQuery("select e from Education where e.resumeId = :resumeId", Education.class) + .setParameter("resumeId", resumeID) + .getResultList(); + + return findEducations; + } +} diff --git a/src/main/java/com/devit/user/service/ResumeService.java b/src/main/java/com/devit/user/service/ResumeService.java index dfafe6f..4101442 100644 --- a/src/main/java/com/devit/user/service/ResumeService.java +++ b/src/main/java/com/devit/user/service/ResumeService.java @@ -1,22 +1,32 @@ package com.devit.user.service; +import com.devit.user.dto.EditResumeRequest; +import com.devit.user.entity.Award; import com.devit.user.entity.Resume; import com.devit.user.entity.User; +import com.devit.user.repository.AwardRepository; import com.devit.user.repository.ResumeRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service @Transactional @RequiredArgsConstructor public class ResumeService { private final ResumeRepository resumeRepository; -// public UUID saveResume(Resume resume) { -// -// } + private final AwardRepository awardRepository; + + public Resume save(EditResumeRequest editResumeRequest, UUID userId) { + List awardList = editResumeRequest.getAwards().stream() + .map(awardRepository::save) + .collect(Collectors.toList()); + + } public Resume findByUser(User user) { return resumeRepository.findByUser(user); } From b6cf80bca384002061007f2f6337241b6bc10334 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Tue, 12 Jul 2022 02:19:36 +0900 Subject: [PATCH 02/17] Update README.md --- README.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a3ba1d..89fa20c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ -# DevitUser -Devit User Domain +# Devit +

+ +

+경험이 많고 실력 있는 개발자에게 도움을 받기 위한 플랫폼입니다.
+기업 또는 개인에게 알맞는 개발자의 스펙과 원하는 직무를 등록하여 구인하고 개발자는 확인 후 지원서를 넣어 서로가 만족하는 상황이 되었을 때 계약이 진행될 수 있도록 중개하는 웹 사이트입니다.
+ + +## Devit User Service +Devit 유저 서비스입니다.
+유저의 회원가입 로직을 인증 서버와 RabbitMQ 비동기 이벤트로 처리합니다.
+유저 프로필, 이력서를 관리합니다.
+이력서로는, 카테고리 직종, 학적, 경력, 수상 등이 있습니다.
+개발 중에 있습니다.
+이력서에 관한 API 완성되면, ERD API 명세서 업로드 예정입니다.
+ +## API List + + +# link to another repo + +- eureka server : https://github.com/ekgpgdi/devit-eureka-server +- gateway : https://github.com/ekgpgdi/devit-gateway +- certification service : https://github.com/ekgpgdi/devit-certification-service +- board : https://github.com/kimziaco/devit-board +- user : https://github.com/eet43/devit-user +- chat : https://github.com/eet43/devit-chat From f705faa3bccead16b69562d1b288990e6e623e42 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Tue, 12 Jul 2022 15:52:57 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=84=9C=20=EB=B6=80=EB=B6=84=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이력의 각종 일대다 카테고리 부분 후에 무조건 fetch join 으로 바꿔야함 시간이 없으니 우선 프론트 먼저 개발하자 이력서 수정 테스트까지 모두 완료 --- build.gradle | 1 + .../user/controller/ResumeController.java | 128 +++++++++--------- .../devit/user/controller/UserController.java | 2 +- .../com/devit/user/dto/EditResumeRequest.java | 1 + .../java/com/devit/user/entity/Award.java | 9 +- .../java/com/devit/user/entity/Career.java | 5 +- .../java/com/devit/user/entity/Education.java | 9 +- .../java/com/devit/user/entity/Resume.java | 6 +- src/main/java/com/devit/user/entity/User.java | 7 +- .../com/devit/user/message/CustomMessage.java | 2 +- .../devit/user/message/RabbitMqReceiver.java | 2 +- .../user/repository/AwardRepository.java | 7 - .../user/repository/CareerRepository.java | 22 +++ .../user/repository/EducationRepository.java | 7 - .../user/repository/ResumeRepository.java | 7 +- .../devit/user/repository/UserRepository.java | 7 + .../com/devit/user/service/ResumeService.java | 46 +++++-- src/main/resources/application.yml | 2 +- .../devit/user/service/ResumeServiceTest.java | 97 +++++++++++++ .../devit/user/service/UserServiceTest.java | 38 ++++++ 20 files changed, 289 insertions(+), 116 deletions(-) create mode 100644 src/main/java/com/devit/user/repository/CareerRepository.java create mode 100644 src/test/java/com/devit/user/service/ResumeServiceTest.java create mode 100644 src/test/java/com/devit/user/service/UserServiceTest.java diff --git a/build.gradle b/build.gradle index 5319894..b2f790d 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,7 @@ dependencies { // https://mvnrepository.com/artifact/org.json/json implementation group: 'org.json', name: 'json', version: '20160810' + implementation 'com.fasterxml.jackson.core:jackson-databind' } diff --git a/src/main/java/com/devit/user/controller/ResumeController.java b/src/main/java/com/devit/user/controller/ResumeController.java index f5c0f7f..91e8ed9 100644 --- a/src/main/java/com/devit/user/controller/ResumeController.java +++ b/src/main/java/com/devit/user/controller/ResumeController.java @@ -1,64 +1,64 @@ -package com.devit.user.controller; - -import com.devit.user.dto.EditResumeRequest; -import com.devit.user.entity.Category; -import com.devit.user.entity.Education; -import com.devit.user.entity.User; -import com.devit.user.exception.NoResourceException; -import com.devit.user.service.CategoryService; -import com.devit.user.service.ResumeService; -import com.devit.user.service.UserService; -import com.devit.user.util.HttpStatusChangeInt; -import io.swagger.annotations.ApiOperation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.json.JSONObject; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Null; -import java.util.Base64; -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; - - -/** - * 1. 이력서 수정. - * - */ -@Slf4j -@RestController -@RequiredArgsConstructor -public class ResumeController { - - private final ResumeService resumeService; - private final CategoryService categoryService; - private final UserService userService; - - @PutMapping("/api/users/resumes") - @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") - public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { - - String[] chunks = data.split("\\."); - Base64.Decoder decoder = Base64.getDecoder(); - String payload = new String(decoder.decode(chunks[1])); - - JSONObject jsonObject = new JSONObject(payload); - String sample = jsonObject.getString("uuid"); - UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 - - User findUser = userService.findUser(uuid); - -// request.getEducations().stream() -// .filter(e->e!=null) -// .map(e->{Education.createEducation(e.)}) - - Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 - - int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); - String path = "api/users/resumes"; - } - -} +//package com.devit.user.controller; +// +//import com.devit.user.dto.EditResumeRequest; +//import com.devit.user.entity.Category; +//import com.devit.user.entity.Education; +//import com.devit.user.entity.User; +//import com.devit.user.exception.NoResourceException; +//import com.devit.user.service.CategoryService; +//import com.devit.user.service.ResumeService; +//import com.devit.user.service.UserService; +//import com.devit.user.util.HttpStatusChangeInt; +//import io.swagger.annotations.ApiOperation; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.json.JSONObject; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import javax.validation.Valid; +//import javax.validation.constraints.Null; +//import java.util.Base64; +//import java.util.List; +//import java.util.UUID; +//import java.util.stream.Collectors; +// +// +///** +// * 1. 이력서 수정. +// * +// */ +//@Slf4j +//@RestController +//@RequiredArgsConstructor +//public class ResumeController { +// +// private final ResumeService resumeService; +// private final CategoryService categoryService; +// private final UserService userService; +// +// @PutMapping("/api/users/resumes") +// @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") +// public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { +// +// String[] chunks = data.split("\\."); +// Base64.Decoder decoder = Base64.getDecoder(); +// String payload = new String(decoder.decode(chunks[1])); +// +// JSONObject jsonObject = new JSONObject(payload); +// String sample = jsonObject.getString("uuid"); +// UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 +// +// User findUser = userService.findUser(uuid); +// +//// request.getEducations().stream() +//// .filter(e->e!=null) +//// .map(e->{Education.createEducation(e.)}) +// +// Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 +// +// int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); +// String path = "api/users/resumes"; +// } +// +//} diff --git a/src/main/java/com/devit/user/controller/UserController.java b/src/main/java/com/devit/user/controller/UserController.java index cd8fd27..7106d92 100644 --- a/src/main/java/com/devit/user/controller/UserController.java +++ b/src/main/java/com/devit/user/controller/UserController.java @@ -47,7 +47,7 @@ public ResponseEntity getProfile(@RequestHeader("Authorization") String data) UUID uuid = UUID.fromString(sample); User findUser = userService.findUser(uuid); - Resume findResume = resumeService.findByUser(findUser); + Resume findResume = resumeService.findByUser(uuid); int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/"; diff --git a/src/main/java/com/devit/user/dto/EditResumeRequest.java b/src/main/java/com/devit/user/dto/EditResumeRequest.java index a84c899..d0d218f 100644 --- a/src/main/java/com/devit/user/dto/EditResumeRequest.java +++ b/src/main/java/com/devit/user/dto/EditResumeRequest.java @@ -12,6 +12,7 @@ @Data @AllArgsConstructor public class EditResumeRequest { + @NotNull private Gender gender; //성별 diff --git a/src/main/java/com/devit/user/entity/Award.java b/src/main/java/com/devit/user/entity/Award.java index a7e27fc..e9f5b21 100644 --- a/src/main/java/com/devit/user/entity/Award.java +++ b/src/main/java/com/devit/user/entity/Award.java @@ -15,9 +15,7 @@ public class Award { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //고유 식별자 값 - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Column(nullable = false, unique = true, columnDefinition = "BINARY(16)", name = "award_id") + @Column(unique = true, columnDefinition = "BINARY(16)", name = "award_id") private UUID awardId; //이력서 고유 id 값 @ManyToOne(fetch = FetchType.LAZY) @@ -31,8 +29,6 @@ public class Award { @Column(name = "end_date") private LocalDate endDate; //종료 날짜 - @Enumerated(value = EnumType.STRING) - private Status awardStatus; //진행 중인지, 종료한 것인지 ? @Column(nullable = false, length = 15) private String competition; //대회 이름 최대 15글자 @@ -45,13 +41,12 @@ public class Award { /* 생성 메서드 */ - public static Award createAward(Resume resume, LocalDate startDate, LocalDate endDate, Status awardStatus + public static Award createAward(Resume resume, LocalDate startDate, LocalDate endDate , String competition, String awards, String content) { Award award = new Award(); award.resume = resume; award.startDate = startDate; award.endDate = endDate; - award.awardStatus = awardStatus; award.competition = competition; award.awards = awards; award.content = content; diff --git a/src/main/java/com/devit/user/entity/Career.java b/src/main/java/com/devit/user/entity/Career.java index db853ef..a67075d 100644 --- a/src/main/java/com/devit/user/entity/Career.java +++ b/src/main/java/com/devit/user/entity/Career.java @@ -12,9 +12,7 @@ public class Career { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //고유 식별자 값 - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Column(nullable = false, unique = true, columnDefinition = "BINARY(16)", name = "career_id") + @Column(unique = true, columnDefinition = "BINARY(16)", name = "career_id") private UUID careerId; //이력서 고유 id 값 @ManyToOne(fetch = FetchType.LAZY) @@ -42,6 +40,7 @@ public class Career { public static Career createCareer(Resume resume, LocalDate startDate, LocalDate endDate, Status careerStatus , String office, String job, String content) { Career career = new Career(); + career.careerId = UUID.randomUUID(); career.resume = resume; career.startDate = startDate; career.endDate = endDate; diff --git a/src/main/java/com/devit/user/entity/Education.java b/src/main/java/com/devit/user/entity/Education.java index 2ac5c28..68180f9 100644 --- a/src/main/java/com/devit/user/entity/Education.java +++ b/src/main/java/com/devit/user/entity/Education.java @@ -4,6 +4,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.CreatedDate; @@ -12,16 +13,13 @@ import java.util.UUID; @Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter @Setter public class Education extends Timestamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //고유 식별자 값 - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Column(nullable = false, unique = true, columnDefinition = "BINARY(16)", name = "education_id") + @Column(unique = true, columnDefinition = "BINARY(16)", name = "education_id") private UUID educationId; //이력서 고유 id 값 @ManyToOne(fetch = FetchType.LAZY) @@ -51,6 +49,7 @@ public class Education extends Timestamped { public static Education createEducation(Resume resume, LocalDate startDate, LocalDate endDate, Status educationStatus , String university, String department, String content) { Education education = new Education(); + education.educationId = UUID.randomUUID(); education.resume = resume; education.startDate = startDate; education.endDate = endDate; diff --git a/src/main/java/com/devit/user/entity/Resume.java b/src/main/java/com/devit/user/entity/Resume.java index 65ae7fd..29e97f0 100644 --- a/src/main/java/com/devit/user/entity/Resume.java +++ b/src/main/java/com/devit/user/entity/Resume.java @@ -58,14 +58,14 @@ public class Resume extends Timestamped { public static Resume createDefaultResume(User user) { Resume resume = new Resume(); resume.user = user; + user.setResume(resume); + resume.resumeId = UUID.randomUUID(); return resume; } - public static Resume editResume(User user, Gender gender, int year, String phone_number, String introduce, Category category, + public static Resume editResume(Resume resume, Gender gender, int year, String phone_number, String introduce, Category category, List educations, List careers, List awards) { - Resume resume = new Resume(); - resume.user = user; resume.gender = gender; resume.year = year; resume.phone_number = phone_number; diff --git a/src/main/java/com/devit/user/entity/User.java b/src/main/java/com/devit/user/entity/User.java index 6affb71..aba4385 100644 --- a/src/main/java/com/devit/user/entity/User.java +++ b/src/main/java/com/devit/user/entity/User.java @@ -5,6 +5,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -18,7 +19,7 @@ */ @Entity -@Getter +@Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) //외부 생성 금지 @Table(name = "user") public class User extends Timestamped { @@ -46,11 +47,11 @@ public class User extends Timestamped { /*생성 메서드 !!!! 반드시 static*/ - public static User signUp(UUID uuid, String email, String name) { + public static User signUp(UUID uuid, String email, String nickName) { User user = new User(); user.userId = uuid; user.email = email; - user.nickName = name; + user.nickName = nickName; return user; } diff --git a/src/main/java/com/devit/user/message/CustomMessage.java b/src/main/java/com/devit/user/message/CustomMessage.java index a19e34c..b8b7a03 100644 --- a/src/main/java/com/devit/user/message/CustomMessage.java +++ b/src/main/java/com/devit/user/message/CustomMessage.java @@ -18,7 +18,7 @@ public class CustomMessage implements Serializable{ public String toString() { return "{" + "email='" + email + '\'' + - ", name='" + nickName + '\'' + + ", nickName='" + nickName + '\'' + ", uuid=" + uuid + '}'; } diff --git a/src/main/java/com/devit/user/message/RabbitMqReceiver.java b/src/main/java/com/devit/user/message/RabbitMqReceiver.java index 7050a35..7cd2827 100644 --- a/src/main/java/com/devit/user/message/RabbitMqReceiver.java +++ b/src/main/java/com/devit/user/message/RabbitMqReceiver.java @@ -34,7 +34,7 @@ public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListe // 소비할 큐를 지정 @Transactional - @RabbitListener(queues = "${spring.rabbitmq.queue}") //유저 큐라고 가정 + @RabbitListener(queues = "${spring.rabbitmq.user.queue}") //유저 큐라고 가정 public void receivedMessage(CustomMessage event) { logger.info("User Details Received is.. " + event); diff --git a/src/main/java/com/devit/user/repository/AwardRepository.java b/src/main/java/com/devit/user/repository/AwardRepository.java index a9c0961..8b259fc 100644 --- a/src/main/java/com/devit/user/repository/AwardRepository.java +++ b/src/main/java/com/devit/user/repository/AwardRepository.java @@ -18,11 +18,4 @@ public Award save(Award award) { return award; } - public Award findAwards(UUID uuid) { - Award findAward = em.createQuery("select a from Award where a.awardId = :awardId", Award.class) - .setParameter("awardId", uuid) - .getSingleResult(); - - return findAward; - } } diff --git a/src/main/java/com/devit/user/repository/CareerRepository.java b/src/main/java/com/devit/user/repository/CareerRepository.java new file mode 100644 index 0000000..52f7411 --- /dev/null +++ b/src/main/java/com/devit/user/repository/CareerRepository.java @@ -0,0 +1,22 @@ +package com.devit.user.repository; + +import com.devit.user.entity.Career; +import com.devit.user.entity.Education; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import javax.persistence.EntityManager; +import java.util.List; +import java.util.UUID; + +@Repository +@RequiredArgsConstructor +public class CareerRepository { + private final EntityManager em; + + public Career save(Career career) { + em.persist(career); + return career; + } + +} diff --git a/src/main/java/com/devit/user/repository/EducationRepository.java b/src/main/java/com/devit/user/repository/EducationRepository.java index 500e9d2..2ee28f8 100644 --- a/src/main/java/com/devit/user/repository/EducationRepository.java +++ b/src/main/java/com/devit/user/repository/EducationRepository.java @@ -19,11 +19,4 @@ public Education save(Education education) { return education; } - public List findAll(UUID resumeID) { - List findEducations = em.createQuery("select e from Education where e.resumeId = :resumeId", Education.class) - .setParameter("resumeId", resumeID) - .getResultList(); - - return findEducations; - } } diff --git a/src/main/java/com/devit/user/repository/ResumeRepository.java b/src/main/java/com/devit/user/repository/ResumeRepository.java index f10f9d2..1d25de0 100644 --- a/src/main/java/com/devit/user/repository/ResumeRepository.java +++ b/src/main/java/com/devit/user/repository/ResumeRepository.java @@ -18,9 +18,10 @@ public UUID save(Resume resume) { return resume.getResumeId(); } - public Resume findByUser(User user) { - return em.createQuery("select r from Resume r where r.user = :user", Resume.class) - .setParameter("user", user) + public Resume findByUser(UUID userID) { + return em.createQuery("select r from Resume r join r.user u " + + "where u.userId = :userId", Resume.class) + .setParameter("userId", userID) .getSingleResult(); } diff --git a/src/main/java/com/devit/user/repository/UserRepository.java b/src/main/java/com/devit/user/repository/UserRepository.java index 57784ee..0697054 100644 --- a/src/main/java/com/devit/user/repository/UserRepository.java +++ b/src/main/java/com/devit/user/repository/UserRepository.java @@ -1,5 +1,6 @@ package com.devit.user.repository; +import com.devit.user.entity.Resume; import com.devit.user.entity.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -31,5 +32,11 @@ public void deleteUser(UUID userId) { .setParameter("userId", userId); } + public Resume findResume(UUID userId) { + return em.createQuery("select u.resume from User u where u.userId = :userId", Resume.class) + .setParameter("userId", userId) + .getSingleResult(); + } + } diff --git a/src/main/java/com/devit/user/service/ResumeService.java b/src/main/java/com/devit/user/service/ResumeService.java index 4101442..7e5f3e6 100644 --- a/src/main/java/com/devit/user/service/ResumeService.java +++ b/src/main/java/com/devit/user/service/ResumeService.java @@ -1,17 +1,13 @@ package com.devit.user.service; import com.devit.user.dto.EditResumeRequest; -import com.devit.user.entity.Award; -import com.devit.user.entity.Resume; -import com.devit.user.entity.User; -import com.devit.user.repository.AwardRepository; -import com.devit.user.repository.ResumeRepository; +import com.devit.user.entity.*; +import com.devit.user.repository.*; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; @Service @@ -20,14 +16,44 @@ public class ResumeService { private final ResumeRepository resumeRepository; private final AwardRepository awardRepository; + private final EducationRepository educationRepository; + private final CareerRepository careerRepository; + + private final CategoryRepository categoryRepository; + private final UserRepository userRepository; + public Resume save(EditResumeRequest editResumeRequest, UUID userId) { - List awardList = editResumeRequest.getAwards().stream() + + Resume resume = userRepository.findResume(userId); + + List educationList = Optional.ofNullable(editResumeRequest.getEducations()).orElse(Collections.emptyList()) + .stream() + .map(educationRepository::save) + .collect(Collectors.toList()); + List awardList = Optional.ofNullable(editResumeRequest.getAwards()).orElse(Collections.emptyList()) + .stream() .map(awardRepository::save) .collect(Collectors.toList()); + List careerList = Optional.ofNullable(editResumeRequest.getCareers()).orElse(Collections.emptyList()) + .stream() + .map(careerRepository::save) + .collect(Collectors.toList()); + +// List awardList = editResumeRequest.getAwards().stream() +// .filter(Objects::nonNull) +// .map(awardRepository::save) +// .collect(Collectors.toList()); +// List careerList = editResumeRequest.getCareers().stream() +// .map(careerRepository::save) +// .collect(Collectors.toList()); + + Category findCategory = categoryRepository.findByName(editResumeRequest.getCategoryName()); + return Resume.editResume(resume, editResumeRequest.getGender(), editResumeRequest.getYear(), editResumeRequest.getPhone_number(), editResumeRequest.getIntroduce(), + findCategory, educationList, careerList, awardList); } - public Resume findByUser(User user) { - return resumeRepository.findByUser(user); + public Resume findByUser(UUID userId) { + return resumeRepository.findByUser(userId); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d0ce9d5..eef8d0f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -24,7 +24,7 @@ spring: jpa: hibernate: - ddl-auto: create + ddl-auto: update properties: hibernate: format_sql: true diff --git a/src/test/java/com/devit/user/service/ResumeServiceTest.java b/src/test/java/com/devit/user/service/ResumeServiceTest.java new file mode 100644 index 0000000..7518adc --- /dev/null +++ b/src/test/java/com/devit/user/service/ResumeServiceTest.java @@ -0,0 +1,97 @@ +package com.devit.user.service; + +import com.devit.user.dto.EditResumeRequest; +import com.devit.user.entity.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +import java.lang.reflect.Array; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) //JUnit 5 테스트 +@SpringBootTest +@Transactional +class ResumeServiceTest { + + @Autowired + CategoryService categoryService; + + @Autowired + UserService userService; + + @Autowired + ResumeService resumeService; + + @Test + public void 이력서_조회() throws Exception { + //given + UUID userId = UUID.fromString("ea579e47-fcff-40df-8cf7-1bc3136a584d"); + User user = userService.findUser(userId); + + //when + Resume resume = resumeService.findByUser(userId); + + //then + } + + @Test + public void 이력서_수정() throws Exception { + + UUID userId = UUID.fromString("ea579e47-fcff-40df-8cf7-1bc3136a584d"); + Resume resume = resumeService.findByUser(userId); + + //given + Category category1 = new Category(); + category1.setName("백엔드"); + category1.setDepth(1L); + categoryService.saveCategory(category1); + + + Category category2 = new Category(); + category2.setName("Spring"); + category2.setDepth(2L); + category2.addParent(category1); + categoryService.saveCategory(category2); + + System.out.println("================카테고리 저장 끝================="); + + + + List educationList = new ArrayList<>(); + List awardList = new ArrayList<>(); + + Education education = Education.createEducation(resume, LocalDate.now(), LocalDate.now(), Status.DONE, "고려대", + "과학기술대학", "졸업"); + Award award1 = Award.createAward(resume, LocalDate.now(), LocalDate.now(), "먹기대회", + "장려상", "얏호"); + Award award2 = Award.createAward(resume, LocalDate.now(), LocalDate.now(), "코딩대회", + "대상", "나이스"); + + educationList.add(education); + awardList.add(award1); + awardList.add(award2); + + System.out.println("================데이터 저장 끝================="); + + EditResumeRequest request = new EditResumeRequest(Gender.MAN, 1998, "01012345678", "", + category2.getName(), educationList, null, awardList); + + + //when + Resume save = resumeService.save(request, userId); + + //then + System.out.println(save); + } +} \ No newline at end of file diff --git a/src/test/java/com/devit/user/service/UserServiceTest.java b/src/test/java/com/devit/user/service/UserServiceTest.java new file mode 100644 index 0000000..5b2e2ac --- /dev/null +++ b/src/test/java/com/devit/user/service/UserServiceTest.java @@ -0,0 +1,38 @@ +package com.devit.user.service; + +import com.devit.user.entity.Resume; +import com.devit.user.entity.User; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + + +@ExtendWith(SpringExtension.class) //JUnit 5 테스트 +@SpringBootTest +@Transactional +class UserServiceTest { + @Autowired + UserService userService; + + @Test + public void 유저_조회() throws Exception { + //given + UUID userId = UUID.fromString("ea579e47-fcff-40df-8cf7-1bc3136a584d"); + + + //when + User user = userService.findUser(userId); + + //then + assertThat(user.getUserId(), is(userId)); + } + +} \ No newline at end of file From 89e1719f15fed03cf4a79ca6ccd44979b9bab651 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Tue, 12 Jul 2022 15:58:59 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=84=9C=20=EB=B6=80=EB=B6=84=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이력의 각종 일대다 카테고리 부분 후에 무조건 fetch join 으로 바꿔야함 시간이 없으니 우선 프론트 먼저 개발하자 이력서 수정 테스트까지 모두 완료 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89fa20c..e2131cf 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,4 @@ Devit 유저 서비스입니다.
- certification service : https://github.com/ekgpgdi/devit-certification-service - board : https://github.com/kimziaco/devit-board - user : https://github.com/eet43/devit-user -- chat : https://github.com/eet43/devit-chat +- chat : https://github.com/eet43/devit-chat \ No newline at end of file From 3dfacef1026956955753fb27d476dfd52c17ca93 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Wed, 13 Jul 2022 14:59:39 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=84=9C=20=EB=B6=80=EB=B6=84=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 유저 조회시, 이력서와 무한루프 빠지는 것을 확인 객체 연관관계를 양방향에서 단방향으로 변경 프론트 개발 시작 API 서버로 배포할 거라, 프론트는 깃에 추가하지 않음 --- .../com/devit/user/controller/UserController.java | 5 ++--- src/main/java/com/devit/user/entity/Resume.java | 8 +++----- .../java/com/devit/user/service/ResumeService.java | 10 ++-------- .../java/com/devit/user/service/UserService.java | 5 +++++ .../com/devit/user/service/ResumeServiceTest.java | 13 +------------ 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/devit/user/controller/UserController.java b/src/main/java/com/devit/user/controller/UserController.java index 7106d92..f4badc9 100644 --- a/src/main/java/com/devit/user/controller/UserController.java +++ b/src/main/java/com/devit/user/controller/UserController.java @@ -32,7 +32,7 @@ public class UserController { private final ResumeService resumeService; /** - * 1. 유저 프로필 조회 + * 1. 유저 프로필 조회 (url : /api/users/) */ @GetMapping("/api/users") @@ -47,13 +47,12 @@ public ResponseEntity getProfile(@RequestHeader("Authorization") String data) UUID uuid = UUID.fromString(sample); User findUser = userService.findUser(uuid); - Resume findResume = resumeService.findByUser(uuid); int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/"; - ResponseProfileDetails responseDetails = new ResponseProfileDetails(new Date(), findUser, findResume, httpStatus, path); + ResponseDetails responseDetails = new ResponseDetails(new Date(), findUser, httpStatus, path); return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); } } diff --git a/src/main/java/com/devit/user/entity/Resume.java b/src/main/java/com/devit/user/entity/Resume.java index 29e97f0..6973c3d 100644 --- a/src/main/java/com/devit/user/entity/Resume.java +++ b/src/main/java/com/devit/user/entity/Resume.java @@ -1,6 +1,7 @@ package com.devit.user.entity; import com.devit.user.util.Timestamped; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -14,6 +15,7 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Resume extends Timestamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -22,9 +24,6 @@ public class Resume extends Timestamped { @Column(nullable = false, unique = true, columnDefinition = "BINARY(16)", name = "resume_id") private UUID resumeId; //이력서 고유 id 값 - @OneToOne(mappedBy = "resume") - private User user; - @Enumerated(value = EnumType.STRING) private Gender gender; //성별 @@ -57,9 +56,8 @@ public class Resume extends Timestamped { public static Resume createDefaultResume(User user) { Resume resume = new Resume(); - resume.user = user; - user.setResume(resume); resume.resumeId = UUID.randomUUID(); + user.setResume(resume); return resume; } diff --git a/src/main/java/com/devit/user/service/ResumeService.java b/src/main/java/com/devit/user/service/ResumeService.java index 7e5f3e6..2df4914 100644 --- a/src/main/java/com/devit/user/service/ResumeService.java +++ b/src/main/java/com/devit/user/service/ResumeService.java @@ -27,6 +27,8 @@ public Resume save(EditResumeRequest editResumeRequest, UUID userId) { Resume resume = userRepository.findResume(userId); + //Null 값 들어왔을 시 비워주기 + List educationList = Optional.ofNullable(editResumeRequest.getEducations()).orElse(Collections.emptyList()) .stream() .map(educationRepository::save) @@ -40,14 +42,6 @@ public Resume save(EditResumeRequest editResumeRequest, UUID userId) { .map(careerRepository::save) .collect(Collectors.toList()); -// List awardList = editResumeRequest.getAwards().stream() -// .filter(Objects::nonNull) -// .map(awardRepository::save) -// .collect(Collectors.toList()); -// List careerList = editResumeRequest.getCareers().stream() -// .map(careerRepository::save) -// .collect(Collectors.toList()); - Category findCategory = categoryRepository.findByName(editResumeRequest.getCategoryName()); return Resume.editResume(resume, editResumeRequest.getGender(), editResumeRequest.getYear(), editResumeRequest.getPhone_number(), editResumeRequest.getIntroduce(), diff --git a/src/main/java/com/devit/user/service/UserService.java b/src/main/java/com/devit/user/service/UserService.java index 2b98358..dadd6ec 100644 --- a/src/main/java/com/devit/user/service/UserService.java +++ b/src/main/java/com/devit/user/service/UserService.java @@ -1,5 +1,6 @@ package com.devit.user.service; +import com.devit.user.entity.Resume; import com.devit.user.entity.User; import com.devit.user.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -30,4 +31,8 @@ public User findUser(UUID userId) { return userRepository.findByUUID(userId); } + public Resume findResume(UUID userId) { + return userRepository.findResume(userId); + } + } diff --git a/src/test/java/com/devit/user/service/ResumeServiceTest.java b/src/test/java/com/devit/user/service/ResumeServiceTest.java index 7518adc..43a55e8 100644 --- a/src/test/java/com/devit/user/service/ResumeServiceTest.java +++ b/src/test/java/com/devit/user/service/ResumeServiceTest.java @@ -33,23 +33,12 @@ class ResumeServiceTest { @Autowired ResumeService resumeService; - @Test - public void 이력서_조회() throws Exception { - //given - UUID userId = UUID.fromString("ea579e47-fcff-40df-8cf7-1bc3136a584d"); - User user = userService.findUser(userId); - - //when - Resume resume = resumeService.findByUser(userId); - - //then - } @Test public void 이력서_수정() throws Exception { UUID userId = UUID.fromString("ea579e47-fcff-40df-8cf7-1bc3136a584d"); - Resume resume = resumeService.findByUser(userId); + Resume resume = userService.findResume(userId); //given Category category1 = new Category(); From 4ad8f95be653ee59675ee3d63ab8969dec26c974 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Thu, 14 Jul 2022 01:29:40 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=84=9C=20=EC=A0=84=EC=86=A1=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 게시판 화면에서, 이력서 전송 버튼 누를 시, 게시판 서버와 메시지큐 이벤트 처리, 현재는 boardId 를 받아, userId 를 더해 이벤트 처리 중 --- .../user/controller/ResumeController.java | 154 ++++++++++-------- .../com/devit/user/dto/SendResumeMessage.java | 13 ++ .../com/devit/user/dto/SendResumeRequest.java | 12 ++ .../dto/response/ResponseMessageDetails.java | 16 ++ .../devit/user/message/RabbitMqSender.java | 26 +++ 5 files changed, 157 insertions(+), 64 deletions(-) create mode 100644 src/main/java/com/devit/user/dto/SendResumeMessage.java create mode 100644 src/main/java/com/devit/user/dto/SendResumeRequest.java create mode 100644 src/main/java/com/devit/user/dto/response/ResponseMessageDetails.java create mode 100644 src/main/java/com/devit/user/message/RabbitMqSender.java diff --git a/src/main/java/com/devit/user/controller/ResumeController.java b/src/main/java/com/devit/user/controller/ResumeController.java index 91e8ed9..72ed49f 100644 --- a/src/main/java/com/devit/user/controller/ResumeController.java +++ b/src/main/java/com/devit/user/controller/ResumeController.java @@ -1,64 +1,90 @@ -//package com.devit.user.controller; -// -//import com.devit.user.dto.EditResumeRequest; -//import com.devit.user.entity.Category; -//import com.devit.user.entity.Education; -//import com.devit.user.entity.User; -//import com.devit.user.exception.NoResourceException; -//import com.devit.user.service.CategoryService; -//import com.devit.user.service.ResumeService; -//import com.devit.user.service.UserService; -//import com.devit.user.util.HttpStatusChangeInt; -//import io.swagger.annotations.ApiOperation; -//import lombok.RequiredArgsConstructor; -//import lombok.extern.slf4j.Slf4j; -//import org.json.JSONObject; -//import org.springframework.http.ResponseEntity; -//import org.springframework.web.bind.annotation.*; -// -//import javax.validation.Valid; -//import javax.validation.constraints.Null; -//import java.util.Base64; -//import java.util.List; -//import java.util.UUID; -//import java.util.stream.Collectors; -// -// -///** -// * 1. 이력서 수정. -// * -// */ -//@Slf4j -//@RestController -//@RequiredArgsConstructor -//public class ResumeController { -// -// private final ResumeService resumeService; -// private final CategoryService categoryService; -// private final UserService userService; -// -// @PutMapping("/api/users/resumes") -// @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") -// public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { -// -// String[] chunks = data.split("\\."); -// Base64.Decoder decoder = Base64.getDecoder(); -// String payload = new String(decoder.decode(chunks[1])); -// -// JSONObject jsonObject = new JSONObject(payload); -// String sample = jsonObject.getString("uuid"); -// UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 -// -// User findUser = userService.findUser(uuid); -// -//// request.getEducations().stream() -//// .filter(e->e!=null) -//// .map(e->{Education.createEducation(e.)}) -// -// Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 -// -// int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); -// String path = "api/users/resumes"; -// } -// -//} +package com.devit.user.controller; + +import com.devit.user.dto.EditResumeRequest; +import com.devit.user.dto.SendResumeMessage; +import com.devit.user.dto.response.ResponseDetails; +import com.devit.user.dto.SendResumeRequest; +import com.devit.user.entity.Resume; +import com.devit.user.exception.NoResourceException; +import com.devit.user.message.RabbitMqSender; +import com.devit.user.service.CategoryService; +import com.devit.user.service.ResumeService; +import com.devit.user.service.UserService; +import com.devit.user.util.HttpStatusChangeInt; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Base64; +import java.util.Date; +import java.util.UUID; + + +/** + * 1. 이력서 수정. + * + */ +@Slf4j +@RestController +@RequiredArgsConstructor +public class ResumeController { + + private final ResumeService resumeService; + private final CategoryService categoryService; + private final UserService userService; + private final RabbitMqSender rabbitMqSender; + + @PutMapping("/api/users/resumes") //수정되야함 + @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") + public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { + + String[] chunks = data.split("\\."); + Base64.Decoder decoder = Base64.getDecoder(); + String payload = new String(decoder.decode(chunks[1])); + + JSONObject jsonObject = new JSONObject(payload); + String sample = jsonObject.getString("uuid"); + UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 + + // Category findCategory = categoryService.findCategoryByName(request.getCategoryName()); //카테고리 찾아오기 + + + Resume editResume = resumeService.save(request, uuid); + + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); + String path = "api/users/resumes"; + + ResponseDetails responseDetails = new ResponseDetails(new Date(), editResume, httpStatus, path); + return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); + } + + @PostMapping("/api/users/resumes") + @ApiOperation(value = "이력서 전송", notes = "이력서를 전송합니다.") + public ResponseEntity sendResume(@RequestHeader("Authorization") String data, @RequestBody @Valid SendResumeRequest request) { + String[] chunks = data.split("\\."); + Base64.Decoder decoder = Base64.getDecoder(); + String payload = new String(decoder.decode(chunks[1])); + + JSONObject jsonObject = new JSONObject(payload); + String sample = jsonObject.getString("uuid"); + UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 + + SendResumeMessage sendResumeMessage = new SendResumeMessage(uuid, request.getBoardId()); + rabbitMqSender.send(sendResumeMessage); + + String message = "이력서 전송 완료"; + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); + String path = "api/users/resumes"; + + + ResponseDetails responseDetails = new ResponseDetails(new Date(), message, httpStatus, path); + return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); + } + + +} diff --git a/src/main/java/com/devit/user/dto/SendResumeMessage.java b/src/main/java/com/devit/user/dto/SendResumeMessage.java new file mode 100644 index 0000000..fe010e7 --- /dev/null +++ b/src/main/java/com/devit/user/dto/SendResumeMessage.java @@ -0,0 +1,13 @@ +package com.devit.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.UUID; + +@Data +@AllArgsConstructor +public class SendResumeMessage { + private UUID userId; + private UUID boardId; +} diff --git a/src/main/java/com/devit/user/dto/SendResumeRequest.java b/src/main/java/com/devit/user/dto/SendResumeRequest.java new file mode 100644 index 0000000..128531d --- /dev/null +++ b/src/main/java/com/devit/user/dto/SendResumeRequest.java @@ -0,0 +1,12 @@ +package com.devit.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.UUID; + +@Data +@AllArgsConstructor +public class SendResumeRequest { + private UUID boardId; +} diff --git a/src/main/java/com/devit/user/dto/response/ResponseMessageDetails.java b/src/main/java/com/devit/user/dto/response/ResponseMessageDetails.java new file mode 100644 index 0000000..86a5e2e --- /dev/null +++ b/src/main/java/com/devit/user/dto/response/ResponseMessageDetails.java @@ -0,0 +1,16 @@ +package com.devit.user.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Date; + +@Getter +@AllArgsConstructor +public class ResponseMessageDetails { + + private Date timestamp; + private String message; + private int httpStatus; + private String path; +} \ No newline at end of file diff --git a/src/main/java/com/devit/user/message/RabbitMqSender.java b/src/main/java/com/devit/user/message/RabbitMqSender.java new file mode 100644 index 0000000..3666371 --- /dev/null +++ b/src/main/java/com/devit/user/message/RabbitMqSender.java @@ -0,0 +1,26 @@ +package com.devit.user.message; + +import com.devit.user.dto.SendResumeMessage; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class RabbitMqSender { + // RabbitTemplate 클래스를 사용하면 RabbitMQ로 메시지를 보내고 받을 수 있다. + private RabbitTemplate rabbitTemplate; + + @Autowired + public RabbitMqSender(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + @Value("${spring.rabbitmq.user.exchange}") + private String exchange; + @Value("${spring.rabbitmq.routingkey}") + private String routingkey; + + public void send(SendResumeMessage sendResumeMessage) { + rabbitTemplate.convertAndSend(exchange, routingkey, sendResumeMessage); + } +} From e5e1644e43aded77747f046297b17a4747cca24a Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Mon, 18 Jul 2022 15:54:58 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EB=8C=80=EA=B3=B5=EC=82=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 이력서와 학력, 수상, 경력 사항들 일대일 관계로 변경 2. 유저 생성시, 기본 정보들 모두 저장. 3. dirty check 를 통해 update 문 처리 --- .../user/controller/ResumeController.java | 5 +- .../java/com/devit/user/dto/EditAwardDto.java | 28 ++++++++ .../com/devit/user/dto/EditCareerDto.java | 38 ++++++++++ .../com/devit/user/dto/EditEducationDto.java | 42 +++++++++++ .../com/devit/user/dto/EditResumeRequest.java | 24 ++++--- .../java/com/devit/user/entity/Award.java | 21 ++++-- .../java/com/devit/user/entity/Career.java | 22 ++++-- .../java/com/devit/user/entity/Category.java | 5 ++ .../java/com/devit/user/entity/Education.java | 23 +++++-- .../java/com/devit/user/entity/Gender.java | 17 ++++- .../java/com/devit/user/entity/Resume.java | 15 ++-- .../java/com/devit/user/entity/Status.java | 16 ++++- .../devit/user/message/RabbitMqReceiver.java | 19 +++-- .../com/devit/user/service/ResumeService.java | 69 ++++++++++++++----- 14 files changed, 284 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/devit/user/dto/EditAwardDto.java create mode 100644 src/main/java/com/devit/user/dto/EditCareerDto.java create mode 100644 src/main/java/com/devit/user/dto/EditEducationDto.java diff --git a/src/main/java/com/devit/user/controller/ResumeController.java b/src/main/java/com/devit/user/controller/ResumeController.java index 72ed49f..ffe1060 100644 --- a/src/main/java/com/devit/user/controller/ResumeController.java +++ b/src/main/java/com/devit/user/controller/ResumeController.java @@ -41,7 +41,7 @@ public class ResumeController { @PutMapping("/api/users/resumes") //수정되야함 @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") - public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody @Valid EditResumeRequest request) throws NoResourceException { + public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody EditResumeRequest request) throws NoResourceException { String[] chunks = data.split("\\."); Base64.Decoder decoder = Base64.getDecoder(); @@ -56,7 +56,7 @@ public ResponseEntity editResume(@RequestHeader("Authorization") String data, Resume editResume = resumeService.save(request, uuid); - int httpStatus = HttpStatusChangeInt.ChangeStatusCode("Edited"); + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/resumes"; ResponseDetails responseDetails = new ResponseDetails(new Date(), editResume, httpStatus, path); @@ -74,6 +74,7 @@ public ResponseEntity sendResume(@RequestHeader("Authorization") String data, String sample = jsonObject.getString("uuid"); UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 + SendResumeMessage sendResumeMessage = new SendResumeMessage(uuid, request.getBoardId()); rabbitMqSender.send(sendResumeMessage); diff --git a/src/main/java/com/devit/user/dto/EditAwardDto.java b/src/main/java/com/devit/user/dto/EditAwardDto.java new file mode 100644 index 0000000..195ffcc --- /dev/null +++ b/src/main/java/com/devit/user/dto/EditAwardDto.java @@ -0,0 +1,28 @@ +package com.devit.user.dto; + +import com.devit.user.entity.Status; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.persistence.Column; +import java.time.LocalDate; +@Getter +@AllArgsConstructor +public class EditAwardDto { + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; //시작 날짜 + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; //종료 날짜 + + private String competition; //대회 이름 최대 15글자 + + private String awards; //수상 내용 최대 10글자 + + private String content; //추가 자기소개 + + public EditAwardDto() { + + } +} diff --git a/src/main/java/com/devit/user/dto/EditCareerDto.java b/src/main/java/com/devit/user/dto/EditCareerDto.java new file mode 100644 index 0000000..089b3e9 --- /dev/null +++ b/src/main/java/com/devit/user/dto/EditCareerDto.java @@ -0,0 +1,38 @@ +package com.devit.user.dto; + +import com.devit.user.entity.Status; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.persistence.Column; +import java.time.LocalDate; +import java.util.Arrays; + +@Getter @AllArgsConstructor +public class EditCareerDto { + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; //시작 날짜 + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; //종료 날짜 + + private String careerStatus; //진행 중인지, 종료한 것인지 ? + + private String office; //회사 이름 최대 15글자 + + private String job; //학과 이름 최대 15글자 + + private String content; //추가 자기소개 + + public EditCareerDto() { + + } + + public static Status of(String code) { + return Arrays.stream(Status.values()) + .filter(r -> r.getLabel().equals(code)) + .findAny() + .orElse(Status.ING); + } +} diff --git a/src/main/java/com/devit/user/dto/EditEducationDto.java b/src/main/java/com/devit/user/dto/EditEducationDto.java new file mode 100644 index 0000000..9145f83 --- /dev/null +++ b/src/main/java/com/devit/user/dto/EditEducationDto.java @@ -0,0 +1,42 @@ +package com.devit.user.dto; + +import com.devit.user.entity.Gender; +import com.devit.user.entity.Resume; +import com.devit.user.entity.Status; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.persistence.*; +import java.time.LocalDate; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public class EditEducationDto { + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; //시작 날짜 + + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; //종료 날짜 + + private String educationStatus; //진행 중인지, 종료한 것인지 ? + + private String university; //학교 이름 최대 15글자 + + private String department; //학과 이름 최대 20글자 + + private String content; //추가 자기소개 + + public EditEducationDto() { + + } + + public static Status of(String code) { + return Arrays.stream(Status.values()) + .filter(r -> r.getLabel().equals(code)) + .findAny() + .orElse(Status.ING); + } +} diff --git a/src/main/java/com/devit/user/dto/EditResumeRequest.java b/src/main/java/com/devit/user/dto/EditResumeRequest.java index d0d218f..e7d50a7 100644 --- a/src/main/java/com/devit/user/dto/EditResumeRequest.java +++ b/src/main/java/com/devit/user/dto/EditResumeRequest.java @@ -7,27 +7,35 @@ import javax.persistence.*; import javax.validation.constraints.NotNull; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; @Data @AllArgsConstructor public class EditResumeRequest { - @NotNull - private Gender gender; //성별 + private String gender; //성별 - @NotNull private int year; //출생년도 - @NotNull private String phone_number; //유저 핸드폰 번호 private String introduce; //자기소개 - @NotNull private String categoryName; //현재 직종 카테고리 (서버파트 => 스프링) - private List educations = new ArrayList<>(); //학력사항 추가 가능 일대다 - private List careers = new ArrayList<>(); //경력사항 추가 가능 일대다 - private List awards = new ArrayList<>(); //수상 및 활동 추가 가능 일대다 + private EditEducationDto educations;//학력사항 추가 가능 일대다 + private EditCareerDto careers; //경력사항 추가 가능 일대다 + private EditAwardDto awards; //수상 및 활동 추가 가능 일대다 + + public EditResumeRequest() { + + } + + public static Gender of(String code) { + return Arrays.stream(Gender.values()) + .filter(r -> r.getLabel().equals(code)) + .findAny() + .orElse(Gender.MAN); + } } diff --git a/src/main/java/com/devit/user/entity/Award.java b/src/main/java/com/devit/user/entity/Award.java index e9f5b21..38e633e 100644 --- a/src/main/java/com/devit/user/entity/Award.java +++ b/src/main/java/com/devit/user/entity/Award.java @@ -1,8 +1,10 @@ package com.devit.user.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.GenericGenerator; +import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.time.LocalDate; @@ -18,33 +20,40 @@ public class Award { @Column(unique = true, columnDefinition = "BINARY(16)", name = "award_id") private UUID awardId; //이력서 고유 id 값 - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "resume_id") + @JsonIgnore private Resume resume; //매칭되는 이력서 다대일 @Column(name = "start_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startDate; //시작 날짜 @Column(name = "end_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate endDate; //종료 날짜 - @Column(nullable = false, length = 15) + @Column(length = 15) private String competition; //대회 이름 최대 15글자 - @Column(nullable = false, length = 10) + @Column(length = 10) private String awards; //수상 내용 최대 10글자 private String content; //추가 자기소개 + public static Award createDefaultAward(Resume resume) { + Award award = new Award(); + award.awardId = UUID.randomUUID(); + award.resume = resume; + return award; + } /* 생성 메서드 */ - public static Award createAward(Resume resume, LocalDate startDate, LocalDate endDate + public static Award editAward(Award award, LocalDate startDate, LocalDate endDate , String competition, String awards, String content) { - Award award = new Award(); - award.resume = resume; award.startDate = startDate; award.endDate = endDate; award.competition = competition; diff --git a/src/main/java/com/devit/user/entity/Career.java b/src/main/java/com/devit/user/entity/Career.java index a67075d..0edb9b0 100644 --- a/src/main/java/com/devit/user/entity/Career.java +++ b/src/main/java/com/devit/user/entity/Career.java @@ -1,6 +1,8 @@ package com.devit.user.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.hibernate.annotations.GenericGenerator; +import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.time.LocalDate; @@ -15,33 +17,41 @@ public class Career { @Column(unique = true, columnDefinition = "BINARY(16)", name = "career_id") private UUID careerId; //이력서 고유 id 값 - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "resume_id") + @JsonIgnore private Resume resume; //매칭되는 이력서 다대일 @Column(name = "start_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startDate; //시작 날짜 @Column(name = "end_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate endDate; //종료 날짜 @Enumerated(value = EnumType.STRING) private Status careerStatus; //진행 중인지, 종료한 것인지 ? - @Column(nullable = false, length = 15) + @Column(length = 15) private String office; //회사 이름 최대 15글자 - @Column(nullable = false, length = 15) + @Column(length = 15) private String job; //학과 이름 최대 15글자 private String content; //추가 자기소개 - /* 생성 메서드 */ - public static Career createCareer(Resume resume, LocalDate startDate, LocalDate endDate, Status careerStatus - , String office, String job, String content) { + + public static Career createDefaultCareer(Resume resume) { Career career = new Career(); career.careerId = UUID.randomUUID(); career.resume = resume; + return career; + } + + /* 생성 메서드 */ + public static Career editCareer(Career career, LocalDate startDate, LocalDate endDate, Status careerStatus + , String office, String job, String content) { career.startDate = startDate; career.endDate = endDate; career.careerStatus = careerStatus; diff --git a/src/main/java/com/devit/user/entity/Category.java b/src/main/java/com/devit/user/entity/Category.java index ac18d3e..071c8ef 100644 --- a/src/main/java/com/devit/user/entity/Category.java +++ b/src/main/java/com/devit/user/entity/Category.java @@ -1,5 +1,7 @@ package com.devit.user.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,6 +13,7 @@ @Entity @Getter @Setter +@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Category { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -20,6 +23,7 @@ public class Category { @Column(nullable = false, unique = true, length = 10) private String name; //카테고리 이름 + @JsonIgnore @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Category parent; @@ -27,6 +31,7 @@ public class Category { @OneToMany(mappedBy = "parent") private List children = new ArrayList<>(); + @JsonIgnore @OneToMany(mappedBy = "category") private List resumes = new ArrayList<>(); diff --git a/src/main/java/com/devit/user/entity/Education.java b/src/main/java/com/devit/user/entity/Education.java index 68180f9..23385e5 100644 --- a/src/main/java/com/devit/user/entity/Education.java +++ b/src/main/java/com/devit/user/entity/Education.java @@ -1,12 +1,14 @@ package com.devit.user.entity; import com.devit.user.util.Timestamped; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.CreatedDate; +import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.time.LocalDate; @@ -22,35 +24,42 @@ public class Education extends Timestamped { @Column(unique = true, columnDefinition = "BINARY(16)", name = "education_id") private UUID educationId; //이력서 고유 id 값 - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "resume_id") + @JsonIgnore private Resume resume; //매칭되는 이력서 다대일 @Column(name = "start_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate startDate; //시작 날짜 @Column(name = "end_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate endDate; //종료 날짜 @Enumerated(value = EnumType.STRING) private Status educationStatus; //진행 중인지, 종료한 것인지 ? - @Column(nullable = false, length = 15) + @Column(length = 15) private String university; //학교 이름 최대 15글자 - @Column(nullable = false, length = 20) + @Column(length = 20) private String department; //학과 이름 최대 20글자 private String content; //추가 자기소개 + public static Education createDefaultEducation(Resume resume) { + Education education = new Education(); + education.educationId = UUID.randomUUID(); + education.resume = resume; + return education; + } + /* 생성 메서드 */ - public static Education createEducation(Resume resume, LocalDate startDate, LocalDate endDate, Status educationStatus + public static Education editEducation(Education education, LocalDate startDate, LocalDate endDate, Status educationStatus , String university, String department, String content) { - Education education = new Education(); - education.educationId = UUID.randomUUID(); - education.resume = resume; education.startDate = startDate; education.endDate = endDate; education.educationStatus = educationStatus; diff --git a/src/main/java/com/devit/user/entity/Gender.java b/src/main/java/com/devit/user/entity/Gender.java index c1a8b84..531718d 100644 --- a/src/main/java/com/devit/user/entity/Gender.java +++ b/src/main/java/com/devit/user/entity/Gender.java @@ -1,5 +1,20 @@ package com.devit.user.entity; +import lombok.Getter; + +@Getter public enum Gender { - MAN, WOMAN + MAN("MAN"), + WOMAN("WOMAN"); + + private String label; + + Gender(String label) { + this.label = label; + } + + public String label() { + return label; + } + } diff --git a/src/main/java/com/devit/user/entity/Resume.java b/src/main/java/com/devit/user/entity/Resume.java index 6973c3d..94688c9 100644 --- a/src/main/java/com/devit/user/entity/Resume.java +++ b/src/main/java/com/devit/user/entity/Resume.java @@ -39,14 +39,14 @@ public class Resume extends Timestamped { @JoinColumn(name = "category_id") private Category category; //현재 직종 카테고리 (서버파트 => 스프링) - @OneToMany(mappedBy = "resume", cascade = CascadeType.ALL) - private List educations = new ArrayList<>(); //학력사항 추가 가능 일대다 + @OneToOne(mappedBy = "resume", cascade = CascadeType.ALL) + private Education educations; //학력사항 추가 가능 일대일 - @OneToMany(mappedBy = "resume", cascade = CascadeType.ALL) - private List careers = new ArrayList<>(); //경력사항 추가 가능 일대다 + @OneToOne(mappedBy = "resume", cascade = CascadeType.ALL) + private Career careers; //경력사항 추가 가능 일대일 - @OneToMany(mappedBy = "resume", cascade = CascadeType.ALL) - private List awards = new ArrayList<>(); //수상 및 활동 추가 가능 일대다 + @OneToOne(mappedBy = "resume", cascade = CascadeType.ALL) + private Award awards; //수상 및 활동 추가 가능 일대일 /*생성 메서드*/ /** @@ -62,8 +62,9 @@ public static Resume createDefaultResume(User user) { return resume; } + public static Resume editResume(Resume resume, Gender gender, int year, String phone_number, String introduce, Category category, - List educations, List careers, List awards) { + Education educations, Career careers, Award awards) { resume.gender = gender; resume.year = year; resume.phone_number = phone_number; diff --git a/src/main/java/com/devit/user/entity/Status.java b/src/main/java/com/devit/user/entity/Status.java index b41abb9..4e4a83b 100644 --- a/src/main/java/com/devit/user/entity/Status.java +++ b/src/main/java/com/devit/user/entity/Status.java @@ -1,5 +1,19 @@ package com.devit.user.entity; +import lombok.Getter; + +@Getter public enum Status { - ING, DONE + ING("ING"), + DONE("DONE"); + + private String label; + + Status(String label) { + this.label = label; + } + + public String label() { + return label; + } } diff --git a/src/main/java/com/devit/user/message/RabbitMqReceiver.java b/src/main/java/com/devit/user/message/RabbitMqReceiver.java index 7cd2827..006eefa 100644 --- a/src/main/java/com/devit/user/message/RabbitMqReceiver.java +++ b/src/main/java/com/devit/user/message/RabbitMqReceiver.java @@ -1,9 +1,7 @@ package com.devit.user.message; -import com.devit.user.entity.Resume; -import com.devit.user.entity.User; -import com.devit.user.repository.ResumeRepository; -import com.devit.user.repository.UserRepository; +import com.devit.user.entity.*; +import com.devit.user.repository.*; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -27,6 +25,9 @@ public class RabbitMqReceiver implements RabbitListenerConfigurer { private final UserRepository userRepository; private final ResumeRepository resumeRepository; + private final AwardRepository awardRepository; + private final EducationRepository educationRepository; + private final CareerRepository careerRepository; @Override public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) { @@ -43,8 +44,18 @@ public void receivedMessage(CustomMessage event) { User user = User.signUp(event.getUuid(), event.getEmail(), event.getNickName()); //유저 디비에 유저 저장 UUID user_uuid = userRepository.save(user); Resume resume = Resume.createDefaultResume(user); //해당 유저에 대한 기본 이력서 생성 + UUID resume_uuid = resumeRepository.save(resume); + Education education = Education.createDefaultEducation(resume); + Award award = Award.createDefaultAward(resume); + Career career = Career.createDefaultCareer(resume); + + Education save_edu = educationRepository.save(education); + Award save_award = awardRepository.save(award); + Career save_car = careerRepository.save(career); + //한번에 수정할 수는 없을까 ? + } } diff --git a/src/main/java/com/devit/user/service/ResumeService.java b/src/main/java/com/devit/user/service/ResumeService.java index 2df4914..e6fade2 100644 --- a/src/main/java/com/devit/user/service/ResumeService.java +++ b/src/main/java/com/devit/user/service/ResumeService.java @@ -1,5 +1,8 @@ package com.devit.user.service; +import com.devit.user.dto.EditAwardDto; +import com.devit.user.dto.EditCareerDto; +import com.devit.user.dto.EditEducationDto; import com.devit.user.dto.EditResumeRequest; import com.devit.user.entity.*; import com.devit.user.repository.*; @@ -23,29 +26,59 @@ public class ResumeService { private final UserRepository userRepository; - public Resume save(EditResumeRequest editResumeRequest, UUID userId) { + public Resume save(EditResumeRequest request, UUID userId) { Resume resume = userRepository.findResume(userId); + EditEducationDto eDto = request.getEducations(); + EditAwardDto aDto = request.getAwards(); + EditCareerDto cDto = request.getCareers(); + + Education education = Education.editEducation(resume.getEducations(), eDto.getStartDate(), eDto.getEndDate(), eDto.of(eDto.getEducationStatus()), + eDto.getUniversity(), eDto.getDepartment(), eDto.getContent()); + + Career career = Career.editCareer(resume.getCareers(), cDto.getStartDate(), cDto.getEndDate(), cDto.of(cDto.getCareerStatus()), + cDto.getOffice(), cDto.getJob(), cDto.getContent()); + + Award award = Award.editAward(resume.getAwards(), aDto.getStartDate(), aDto.getEndDate(), aDto.getCompetition(), aDto.getAwards(), aDto.getContent()); + //dirty check 가능 + //Null 값 들어왔을 시 비워주기 - List educationList = Optional.ofNullable(editResumeRequest.getEducations()).orElse(Collections.emptyList()) - .stream() - .map(educationRepository::save) - .collect(Collectors.toList()); - List awardList = Optional.ofNullable(editResumeRequest.getAwards()).orElse(Collections.emptyList()) - .stream() - .map(awardRepository::save) - .collect(Collectors.toList()); - List careerList = Optional.ofNullable(editResumeRequest.getCareers()).orElse(Collections.emptyList()) - .stream() - .map(careerRepository::save) - .collect(Collectors.toList()); - - Category findCategory = categoryRepository.findByName(editResumeRequest.getCategoryName()); - - return Resume.editResume(resume, editResumeRequest.getGender(), editResumeRequest.getYear(), editResumeRequest.getPhone_number(), editResumeRequest.getIntroduce(), - findCategory, educationList, careerList, awardList); +// List educationList = Optional.ofNullable(editResumeRequest.getEducations()).orElse(Collections.emptyList()) +// .stream() +// .map(dto -> { +// Status educationStatus = dto.of(dto.getEducationStatus()); +// Education education = Education.editEducation(resume.get, dto.getStartDate(), dto.getEndDate(), educationStatus, +// dto.getUniversity(), dto.getDepartment(), dto.getContent()); +// return educationRepository.save(education); +// }) +// .collect(Collectors.toList()); + +// List awardList = Optional.ofNullable(editResumeRequest.getAwards()).orElse(Collections.emptyList()) +// .stream() +// .map(dto -> { +// Award award = Award.createAward(resume, dto.getStartDate(), dto.getEndDate(), +// dto.getCompetition(), dto.getAwards(), dto.getContent()); +// return awardRepository.save(award); +// }) +// .collect(Collectors.toList()); +// +// List careerList = Optional.ofNullable(editResumeRequest.getCareers()).orElse(Collections.emptyList()) +// .stream() +// .map(dto -> { +// Status careerStatus = dto.of(dto.getCareerStatus()); +// Career career = Career.createCareer(resume, dto.getStartDate(), dto.getEndDate(), careerStatus, +// dto.getOffice(), dto.getJob(), dto.getContent()); +// return careerRepository.save(career); +// }) +// .collect(Collectors.toList()); + + Category findCategory = categoryRepository.findByName(request.getCategoryName()); + Gender gender = EditResumeRequest.of(request.getGender()); + + return Resume.editResume(resume, gender, request.getYear(), request.getPhone_number(), request.getIntroduce(), + findCategory, education, career, award); } public Resume findByUser(UUID userId) { return resumeRepository.findByUser(userId); From 15720ed8b054702f3263fadbf49f30f6edeaea4e Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 14:56:33 +0900 Subject: [PATCH 08/17] Create main.yml --- .github/workflows/main.yml | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..91643b0 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,87 @@ +# This is a basic workflow to help you get started with Actions + +name: devit user domain server CI/CD + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "feat/user-resume" branch + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] +env: + S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }} + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'temurin' + + - name: Setup MySQL + uses: samin/mysql-action@v1 + with: + character set server: 'utf8' + mysql database: 'devit_user' + mysql user: 'devit' + mysql password: ${{ secrets.MYSQL_PASSWORD }} + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew clean build + + # 디렉토리 생성 + - name: Make Directory + run: mkdir -p deploy + + # Jar 파일 복사 + - name: Copy Jar + run: cp ./build/libs/*.jar ./deploy + + # appspec.yml 파일 복사 + - name: Copy appspec.yml + run: cp appspec.yml ./deploy + + # script files 복사 + - name: Copy script + run: cp ./scripts/*.sh ./deploy + + - name: Make zip file + run: zip -r ./board.zip ./deploy + shell: bash + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-2 + + - name: Upload to S3 + run: aws s3 cp --region ap-northeast-2 ./board.zip s3://${{ secrets.S3_BUCKET_NAME }}/ + + # Deploy + - name: Deploy + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: + aws deploy create-deployment + --application-name DevitBoard + --deployment-group-name board-group + --file-exists-behavior OVERWRITE + --s3-location bucket=${{ secrets.S3_BUCKET_NAME }},bundleType=zip,key=board.zip + --region ap-northeast-2 From 157f6cdc7474ce98dec466383c4430d4f076cc46 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 15:05:34 +0900 Subject: [PATCH 09/17] Update main.yml --- .github/workflows/main.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 91643b0..2ae0fb2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,7 +34,7 @@ jobs: with: character set server: 'utf8' mysql database: 'devit_user' - mysql user: 'devit' + mysql user: 'daehee' mysql password: ${{ secrets.MYSQL_PASSWORD }} - name: Grant execute permission for gradlew @@ -60,7 +60,7 @@ jobs: run: cp ./scripts/*.sh ./deploy - name: Make zip file - run: zip -r ./board.zip ./deploy + run: zip -r ./user.zip ./deploy shell: bash - name: Configure AWS credentials @@ -70,8 +70,6 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-2 - - name: Upload to S3 - run: aws s3 cp --region ap-northeast-2 ./board.zip s3://${{ secrets.S3_BUCKET_NAME }}/ # Deploy - name: Deploy @@ -80,7 +78,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: aws deploy create-deployment - --application-name DevitBoard + --application-name DevitUser --deployment-group-name board-group --file-exists-behavior OVERWRITE --s3-location bucket=${{ secrets.S3_BUCKET_NAME }},bundleType=zip,key=board.zip From 716f0af332537bde8ba827e96271a36fd2a96e6b Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 16:06:51 +0900 Subject: [PATCH 10/17] Update main.yml --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2ae0fb2..5663f76 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -79,7 +79,6 @@ jobs: run: aws deploy create-deployment --application-name DevitUser - --deployment-group-name board-group + --deployment-group-name user-group --file-exists-behavior OVERWRITE - --s3-location bucket=${{ secrets.S3_BUCKET_NAME }},bundleType=zip,key=board.zip --region ap-northeast-2 From 571fa392e102d98517194df348421b1c62cf7d18 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 16:16:57 +0900 Subject: [PATCH 11/17] Update main.yml --- .github/workflows/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5663f76..962dced 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -69,6 +69,9 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-2 + + - name: Upload to S3 + run: aws s3 cp --region ap-northeast-2 ./board.zip s3://${{ secrets.S3_BUCKET_NAME }}/ # Deploy @@ -81,4 +84,5 @@ jobs: --application-name DevitUser --deployment-group-name user-group --file-exists-behavior OVERWRITE + --s3-location bucket=${{ secrets.S3_BUCKET_NAME }},bundleType=zip,key=board.zip --region ap-northeast-2 From 7601c64263634cbcbd849ee7ef4961d2af666f1f Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Fri, 22 Jul 2022 19:15:56 +0900 Subject: [PATCH 12/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A7=88=EB=AC=B4=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 배포해보자. --- appspec.yml | 18 ++++++++ scripts/deploy.sh | 31 +++++++++++++ .../user/controller/CategoryController.java | 20 +++++++-- .../user/controller/ResumeController.java | 30 ++++++++++--- .../devit/user/controller/UserController.java | 22 +++++++++- .../java/com/devit/user/dto/ResumeDto.java | 24 +++++++++++ .../java/com/devit/user/entity/Career.java | 4 ++ .../devit/user/message/RabbitMqSender.java | 9 ++-- .../user/repository/ResumeRepository.java | 1 + .../devit/user/repository/UserRepository.java | 6 +++ .../com/devit/user/service/ResumeService.java | 43 ++++++------------- .../com/devit/user/service/UserService.java | 18 ++++++++ src/main/resources/application.yml | 10 +++-- 13 files changed, 189 insertions(+), 47 deletions(-) create mode 100644 appspec.yml create mode 100644 scripts/deploy.sh create mode 100644 src/main/java/com/devit/user/dto/ResumeDto.java diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 0000000..392b0e1 --- /dev/null +++ b/appspec.yml @@ -0,0 +1,18 @@ +version: 0.0 +os: linux +files: + - source: / + destination: /home/ubuntu/app/ + overwrite: yes + +permissions: + - object: / + pattern: "**" + owner: ubuntu + group: ubuntu + +hooks: + ApplicationStart: + - location: deploy.sh + timeout: 60 + runas: ubuntu \ No newline at end of file diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100644 index 0000000..86a651d --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +REPOSITORY=/home/ubuntu/app + +echo "> 현재 구동 중인 애플리케이션 pid 확인" + +CURRENT_PID=$(pgrep -fla java | grep hayan | awk '{print $1}') + +echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID" + +if [ -z "$CURRENT_PID" ]; then + echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다." +else + echo "> kill -15 $CURRENT_PID" + kill -15 $CURRENT_PID + sleep 5 +fi + +echo "> 새 애플리케이션 배포" + +JAR_NAME=$(ls -tr $REPOSITORY/*SNAPSHOT.jar | tail -n 1) + +echo "> JAR NAME: $JAR_NAME" + +echo "> $JAR_NAME 에 실행권한 추가" + +chmod +x $JAR_NAME + +echo "> $JAR_NAME 실행" + +nohup java -jar -Duser.timezone=Asia/Seoul $JAR_NAME >> $REPOSITORY/nohup.out 2>&1 & \ No newline at end of file diff --git a/src/main/java/com/devit/user/controller/CategoryController.java b/src/main/java/com/devit/user/controller/CategoryController.java index 4c5ea8c..a644189 100644 --- a/src/main/java/com/devit/user/controller/CategoryController.java +++ b/src/main/java/com/devit/user/controller/CategoryController.java @@ -10,6 +10,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -23,24 +24,31 @@ */ @RestController @RequiredArgsConstructor +@Slf4j public class CategoryController { private final CategoryService categoryService; - @PostMapping("api/users/categories/parent") //1 + @PostMapping("/categories/parent") //1 @ApiOperation(value = "부모 카테고리 등록", notes = "부모 카테고리를 등록합니다.") public ResponseEntity saveParentCategory(@RequestBody CreateParentCategoryRequest request) throws NoResourceException { + log.info("category : {} 부모 카테고리를 저장합니다.", request.getName()); + Category category = new Category(); category.setName(request.getName()); category.setDepth(1L); Long saveCategoryId = categoryService.saveCategory(category); + log.info("category : {} 부모 카테고리 Id 를 반환합니다.", saveCategoryId); + + return ResponseEntity.ok().body(saveCategoryId); } - @PostMapping("api/users/categories/children") //2 + @PostMapping("/categories/children") //2 @ApiOperation(value = "자식 카테고리 등록", notes = "자식 카테고리를 등록합니다.") public ResponseEntity saveChildCategory(@RequestBody CreateChildCategoryRequest request) throws NoResourceException { + log.info("category : {} 자식 카테고리를 저장합니다.", request.getName()); Category findParent = categoryService.findCategoryByName(request.getParentName()); @@ -49,12 +57,18 @@ public ResponseEntity saveChildCategory(@RequestBody CreateChildCategoryReque category.setDepth(2L); category.addParent(findParent); + log.info("category : 부모와 자식 카테고리를 연결합니다."); + + Long saveCategoryId = categoryService.saveCategory(category); + log.info("category : {} 자식 카테고리 id를 반환합니다.", saveCategoryId); + + return ResponseEntity.ok().body(saveCategoryId); } - @GetMapping("api/users/categories") //3 + @GetMapping("/categories") //3 @ApiOperation(value = "카테고리 조회", notes = "자식 카테고리를 조회합니다.") public ResponseEntity getCategories() { diff --git a/src/main/java/com/devit/user/controller/ResumeController.java b/src/main/java/com/devit/user/controller/ResumeController.java index ffe1060..726b6ff 100644 --- a/src/main/java/com/devit/user/controller/ResumeController.java +++ b/src/main/java/com/devit/user/controller/ResumeController.java @@ -1,6 +1,7 @@ package com.devit.user.controller; import com.devit.user.dto.EditResumeRequest; +import com.devit.user.dto.ResumeDto; import com.devit.user.dto.SendResumeMessage; import com.devit.user.dto.response.ResponseDetails; import com.devit.user.dto.SendResumeRequest; @@ -22,6 +23,7 @@ import javax.validation.Valid; import java.util.Base64; import java.util.Date; +import java.util.Map; import java.util.UUID; @@ -39,10 +41,12 @@ public class ResumeController { private final UserService userService; private final RabbitMqSender rabbitMqSender; - @PutMapping("/api/users/resumes") //수정되야함 + @PutMapping("/resumes") //수정되야함 @ApiOperation(value = "이력서 수정", notes = "이력서를 수정합니다.") public ResponseEntity editResume(@RequestHeader("Authorization") String data, @RequestBody EditResumeRequest request) throws NoResourceException { + log.info("resume : 이력서를 수정합니다. ex) 자기소개 : {}", request.getIntroduce()); + String[] chunks = data.split("\\."); Base64.Decoder decoder = Base64.getDecoder(); String payload = new String(decoder.decode(chunks[1])); @@ -56,6 +60,8 @@ public ResponseEntity editResume(@RequestHeader("Authorization") String data, Resume editResume = resumeService.save(request, uuid); + log.info("resume : 이력서 수정 왼료 {}", editResume); + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/resumes"; @@ -63,9 +69,9 @@ public ResponseEntity editResume(@RequestHeader("Authorization") String data, return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); } - @PostMapping("/api/users/resumes") + @PostMapping("/resumes") @ApiOperation(value = "이력서 전송", notes = "이력서를 전송합니다.") - public ResponseEntity sendResume(@RequestHeader("Authorization") String data, @RequestBody @Valid SendResumeRequest request) { + public ResponseEntity sendResume(@RequestHeader("Authorization") String data, @RequestBody Map requestObject) { String[] chunks = data.split("\\."); Base64.Decoder decoder = Base64.getDecoder(); String payload = new String(decoder.decode(chunks[1])); @@ -74,11 +80,23 @@ public ResponseEntity sendResume(@RequestHeader("Authorization") String data, String sample = jsonObject.getString("uuid"); UUID uuid = UUID.fromString(sample); //토큰 복호화 완료 + String nickName; //조건문 변수 처리를 못 하는거 떄문에 일단 선언 + + if (!jsonObject.has("nickName")) { + Object obj = userService.findUserName(uuid); + nickName = String.valueOf(obj); + } + else { + nickName = jsonObject.getString("nickName"); // 키 값이 없으면 null 값이면 nullPointException + } + + + ResumeDto resumeDto = new ResumeDto(uuid, nickName, UUID.fromString(requestObject.get("boardId"))); + log.info("resume : 이력서를 전송합니다. {}", resumeDto); + String message = rabbitMqSender.send(resumeDto); - SendResumeMessage sendResumeMessage = new SendResumeMessage(uuid, request.getBoardId()); - rabbitMqSender.send(sendResumeMessage); + log.info("resume : 이력서 전송 결과를 반환합니다. : {}", message); - String message = "이력서 전송 완료"; int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/resumes"; diff --git a/src/main/java/com/devit/user/controller/UserController.java b/src/main/java/com/devit/user/controller/UserController.java index f4badc9..7c609a6 100644 --- a/src/main/java/com/devit/user/controller/UserController.java +++ b/src/main/java/com/devit/user/controller/UserController.java @@ -33,9 +33,10 @@ public class UserController { /** * 1. 유저 프로필 조회 (url : /api/users/) + * 2. 특정 유저 조회 */ - @GetMapping("/api/users") + @GetMapping("/") public ResponseEntity getProfile(@RequestHeader("Authorization") String data) throws NoResourceException { String[] chunks = data.split("\\."); @@ -48,10 +49,29 @@ public ResponseEntity getProfile(@RequestHeader("Authorization") String data) User findUser = userService.findUser(uuid); + log.info("User : 프로필을 조회합니다. {}", findUser); + + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); String path = "api/users/"; + ResponseDetails responseDetails = new ResponseDetails(new Date(), findUser, httpStatus, path); + return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); + } + + @GetMapping("/{uuid}") + public ResponseEntity getProfile(@PathVariable("uuid") UUID userId) throws NoResourceException { + + + User findUser = userService.findUser(userId); + + log.info("User : 해당 이력서를 조회합니다. {}", findUser); + + int httpStatus = HttpStatusChangeInt.ChangeStatusCode("OK"); + String path = "api/users/{uuid}"; + + ResponseDetails responseDetails = new ResponseDetails(new Date(), findUser, httpStatus, path); return new ResponseEntity<>(responseDetails, HttpStatus.CREATED); } diff --git a/src/main/java/com/devit/user/dto/ResumeDto.java b/src/main/java/com/devit/user/dto/ResumeDto.java new file mode 100644 index 0000000..79e25f2 --- /dev/null +++ b/src/main/java/com/devit/user/dto/ResumeDto.java @@ -0,0 +1,24 @@ +package com.devit.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.Serializable; +import java.util.UUID; + +@Data +@AllArgsConstructor +public class ResumeDto implements Serializable { + private UUID userUid; + private String userName; + private UUID boardUid; + + @Override + public String toString() { + return "Resume{" + + "userUid='" + userUid + '\'' + + ", userName='" + userName + '\'' + + ", boardUid='" + boardUid + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/devit/user/entity/Career.java b/src/main/java/com/devit/user/entity/Career.java index 0edb9b0..bcc3642 100644 --- a/src/main/java/com/devit/user/entity/Career.java +++ b/src/main/java/com/devit/user/entity/Career.java @@ -1,6 +1,8 @@ package com.devit.user.entity; import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; +import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import org.springframework.format.annotation.DateTimeFormat; @@ -9,6 +11,8 @@ import java.util.UUID; @Entity +@Getter +@Setter public class Career { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/devit/user/message/RabbitMqSender.java b/src/main/java/com/devit/user/message/RabbitMqSender.java index 3666371..284c302 100644 --- a/src/main/java/com/devit/user/message/RabbitMqSender.java +++ b/src/main/java/com/devit/user/message/RabbitMqSender.java @@ -1,5 +1,6 @@ package com.devit.user.message; +import com.devit.user.dto.ResumeDto; import com.devit.user.dto.SendResumeMessage; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; @@ -15,12 +16,14 @@ public class RabbitMqSender { public RabbitMqSender(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; } - @Value("${spring.rabbitmq.user.exchange}") + @Value("${spring.rabbitmq.board.exchange}") private String exchange; @Value("${spring.rabbitmq.routingkey}") private String routingkey; - public void send(SendResumeMessage sendResumeMessage) { - rabbitTemplate.convertAndSend(exchange, routingkey, sendResumeMessage); + public String send(ResumeDto resumeDto) { + rabbitTemplate.convertAndSend(exchange, routingkey, resumeDto); + + return "메시지 전송 완료"; } } diff --git a/src/main/java/com/devit/user/repository/ResumeRepository.java b/src/main/java/com/devit/user/repository/ResumeRepository.java index 1d25de0..85bc7d0 100644 --- a/src/main/java/com/devit/user/repository/ResumeRepository.java +++ b/src/main/java/com/devit/user/repository/ResumeRepository.java @@ -25,4 +25,5 @@ public Resume findByUser(UUID userID) { .getSingleResult(); } + } diff --git a/src/main/java/com/devit/user/repository/UserRepository.java b/src/main/java/com/devit/user/repository/UserRepository.java index 0697054..3c3ab6c 100644 --- a/src/main/java/com/devit/user/repository/UserRepository.java +++ b/src/main/java/com/devit/user/repository/UserRepository.java @@ -38,5 +38,11 @@ public Resume findResume(UUID userId) { .getSingleResult(); } + public Object findUserName(UUID userId) { + return em.createQuery("select u.name from User u where u.userId = :userId") + .setParameter("userId", userId) + .getSingleResult(); + } + } diff --git a/src/main/java/com/devit/user/service/ResumeService.java b/src/main/java/com/devit/user/service/ResumeService.java index e6fade2..e46c450 100644 --- a/src/main/java/com/devit/user/service/ResumeService.java +++ b/src/main/java/com/devit/user/service/ResumeService.java @@ -7,6 +7,7 @@ import com.devit.user.entity.*; import com.devit.user.repository.*; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +16,7 @@ @Service @Transactional +@Slf4j @RequiredArgsConstructor public class ResumeService { private final ResumeRepository resumeRepository; @@ -29,6 +31,10 @@ public class ResumeService { public Resume save(EditResumeRequest request, UUID userId) { Resume resume = userRepository.findResume(userId); + + log.info("Resume(service) : {} 해당 유저의 이력서를 조회합니다.", resume); + + EditEducationDto eDto = request.getEducations(); EditAwardDto aDto = request.getAwards(); EditCareerDto cDto = request.getCareers(); @@ -36,43 +42,20 @@ public Resume save(EditResumeRequest request, UUID userId) { Education education = Education.editEducation(resume.getEducations(), eDto.getStartDate(), eDto.getEndDate(), eDto.of(eDto.getEducationStatus()), eDto.getUniversity(), eDto.getDepartment(), eDto.getContent()); + log.info("Education(service) : {} 해당 유저의 교육사항을 조회합니다.", education); + + Career career = Career.editCareer(resume.getCareers(), cDto.getStartDate(), cDto.getEndDate(), cDto.of(cDto.getCareerStatus()), cDto.getOffice(), cDto.getJob(), cDto.getContent()); + log.info("Career(service) : {} 해당 유저의 개발사항을 조회합니다.", career); + + Award award = Award.editAward(resume.getAwards(), aDto.getStartDate(), aDto.getEndDate(), aDto.getCompetition(), aDto.getAwards(), aDto.getContent()); //dirty check 가능 + log.info("Award(service) : {} 해당 유저의 수상사항을 조회합니다.", award); - //Null 값 들어왔을 시 비워주기 - -// List educationList = Optional.ofNullable(editResumeRequest.getEducations()).orElse(Collections.emptyList()) -// .stream() -// .map(dto -> { -// Status educationStatus = dto.of(dto.getEducationStatus()); -// Education education = Education.editEducation(resume.get, dto.getStartDate(), dto.getEndDate(), educationStatus, -// dto.getUniversity(), dto.getDepartment(), dto.getContent()); -// return educationRepository.save(education); -// }) -// .collect(Collectors.toList()); - -// List awardList = Optional.ofNullable(editResumeRequest.getAwards()).orElse(Collections.emptyList()) -// .stream() -// .map(dto -> { -// Award award = Award.createAward(resume, dto.getStartDate(), dto.getEndDate(), -// dto.getCompetition(), dto.getAwards(), dto.getContent()); -// return awardRepository.save(award); -// }) -// .collect(Collectors.toList()); -// -// List careerList = Optional.ofNullable(editResumeRequest.getCareers()).orElse(Collections.emptyList()) -// .stream() -// .map(dto -> { -// Status careerStatus = dto.of(dto.getCareerStatus()); -// Career career = Career.createCareer(resume, dto.getStartDate(), dto.getEndDate(), careerStatus, -// dto.getOffice(), dto.getJob(), dto.getContent()); -// return careerRepository.save(career); -// }) -// .collect(Collectors.toList()); Category findCategory = categoryRepository.findByName(request.getCategoryName()); Gender gender = EditResumeRequest.of(request.getGender()); diff --git a/src/main/java/com/devit/user/service/UserService.java b/src/main/java/com/devit/user/service/UserService.java index dadd6ec..1c0b096 100644 --- a/src/main/java/com/devit/user/service/UserService.java +++ b/src/main/java/com/devit/user/service/UserService.java @@ -4,12 +4,14 @@ import com.devit.user.entity.User; import com.devit.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.UUID; @Service +@Slf4j @RequiredArgsConstructor @Transactional(readOnly = true) public class UserService { @@ -18,21 +20,37 @@ public class UserService { @Transactional public UUID saveUser(User user) { + + log.info("User(service) : 새로운 유저를 저장합니다. {}", user); + return userRepository.save(user); } @Transactional public void deleteUser(UUID userId) { + + log.info("User(service) : {} 해당 유저를 삭제합니다.", userId); + userRepository.deleteUser(userId); } public User findUser(UUID userId) { + + log.info("User(service) : {} 해당 유저를 조회합니다.", userId); + return userRepository.findByUUID(userId); } public Resume findResume(UUID userId) { + + log.info("User(service) : {} 해당 유저의 이력서만 조회합니다.", userId); + return userRepository.findResume(userId); } + public Object findUserName(UUID userId) { + return userRepository.findUserName(userId); + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index eef8d0f..ee6d507 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,14 +3,16 @@ jwt: secret: "50g/NGsxw15SwkKw8f+fxuXw6hBrEVYXCgJwyzItp8I=" spring: + main: + allow-bean-definition-overriding: true datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/devit_user?characterEncoding=utf8 - username: devit - password: 1234 + url: jdbc:mysql://database-devit-user.copkmnpqtze8.ap-northeast-2.rds.amazonaws.com:3306/devit_user?characterEncoding=utf8 + username: daehee + password: tjseo1024 rabbitmq: - host: localhost + host: 52.79.236.81 password: 1234 port: 5672 username: devit From 2dc80eefd8b432db2db3d0b55992dc46a6109cb5 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 19:36:28 +0900 Subject: [PATCH 13/17] Update main.yml --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 962dced..340e997 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,9 +6,9 @@ name: devit user domain server CI/CD on: # Triggers the workflow on push or pull request events but only for the "feat/user-resume" branch push: - branches: [ "master" ] + branches: [ "feature/user-resume" ] pull_request: - branches: [ "master" ] + branches: [ "feature/user-resume" ] env: S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }} From 1625f106410378b3f822c298498f683782889347 Mon Sep 17 00:00:00 2001 From: eet43 <1998opening@gmail.com> Date: Fri, 22 Jul 2022 19:38:54 +0900 Subject: [PATCH 14/17] =?UTF-8?q?feat=20=EC=9C=A0=EC=A0=80=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A7=88=EB=AC=B4=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 배포해보자. --- src/main/java/com/devit/user/controller/CategoryController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/devit/user/controller/CategoryController.java b/src/main/java/com/devit/user/controller/CategoryController.java index a644189..a15ea87 100644 --- a/src/main/java/com/devit/user/controller/CategoryController.java +++ b/src/main/java/com/devit/user/controller/CategoryController.java @@ -72,6 +72,8 @@ public ResponseEntity saveChildCategory(@RequestBody CreateChildCategoryReque @ApiOperation(value = "카테고리 조회", notes = "자식 카테고리를 조회합니다.") public ResponseEntity getCategories() { + log.info("category : 카테고리를 조회합니다."); + List findParents = categoryService.findParentCategoires(); List collect = findParents.stream() .map(c -> new GetCategoryResponse(c.getId(), c.getName(), c.getChildren())) From d5fd6c7e4b94dda4262ebbdaef6858637b98c590 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 22 Jul 2022 22:32:02 +0900 Subject: [PATCH 15/17] Delete main.yml --- .github/workflows/main.yml | 88 -------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 340e997..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,88 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: devit user domain server CI/CD - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the "feat/user-resume" branch - push: - branches: [ "feature/user-resume" ] - pull_request: - branches: [ "feature/user-resume" ] -env: - S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }} - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - uses: actions/checkout@v2 - - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'temurin' - - - name: Setup MySQL - uses: samin/mysql-action@v1 - with: - character set server: 'utf8' - mysql database: 'devit_user' - mysql user: 'daehee' - mysql password: ${{ secrets.MYSQL_PASSWORD }} - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew clean build - - # 디렉토리 생성 - - name: Make Directory - run: mkdir -p deploy - - # Jar 파일 복사 - - name: Copy Jar - run: cp ./build/libs/*.jar ./deploy - - # appspec.yml 파일 복사 - - name: Copy appspec.yml - run: cp appspec.yml ./deploy - - # script files 복사 - - name: Copy script - run: cp ./scripts/*.sh ./deploy - - - name: Make zip file - run: zip -r ./user.zip ./deploy - shell: bash - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ap-northeast-2 - - - name: Upload to S3 - run: aws s3 cp --region ap-northeast-2 ./board.zip s3://${{ secrets.S3_BUCKET_NAME }}/ - - - # Deploy - - name: Deploy - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - run: - aws deploy create-deployment - --application-name DevitUser - --deployment-group-name user-group - --file-exists-behavior OVERWRITE - --s3-location bucket=${{ secrets.S3_BUCKET_NAME }},bundleType=zip,key=board.zip - --region ap-northeast-2 From 71fcc01ddae3cf71d353b0005ba2bf8c7eeb164e Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 24 Feb 2023 18:06:48 +0900 Subject: [PATCH 16/17] Update application.yml --- src/main/resources/application.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ee6d507..26acd8a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,13 +7,13 @@ spring: allow-bean-definition-overriding: true datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://database-devit-user.copkmnpqtze8.ap-northeast-2.rds.amazonaws.com:3306/devit_user?characterEncoding=utf8 - username: daehee - password: tjseo1024 + url: + username: + password: rabbitmq: host: 52.79.236.81 - password: 1234 + password: port: 5672 username: devit routingkey: devit.routingkey From d94660a0158df6a752d314b829057e9c88e76914 Mon Sep 17 00:00:00 2001 From: Daisy <59008469+eet43@users.noreply.github.com> Date: Fri, 24 Feb 2023 18:07:01 +0900 Subject: [PATCH 17/17] Update application.yml --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 26acd8a..7c2920a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ # jwt secret key jwt: - secret: "50g/NGsxw15SwkKw8f+fxuXw6hBrEVYXCgJwyzItp8I=" + secret: spring: main: