Skip to content

Commit

Permalink
Merge pull request #381 from daedongbread/develop
Browse files Browse the repository at this point in the history
대동빵 2.0.0
  • Loading branch information
JayPark7821 authored Dec 11, 2023
2 parents 8580a88 + 015e306 commit 9ad8d43
Show file tree
Hide file tree
Showing 135 changed files with 5,221 additions and 496 deletions.
18 changes: 16 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ dependencies {
// mock3S
testImplementation 'io.findify:s3mock_2.13:0.2.6'
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.6.3'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '3.1.4'
// redisson
implementation 'org.redisson:redisson-spring-data-26:3.23.5'
// embedded-redis
implementation(group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2')
// FCM push
Expand All @@ -100,6 +102,18 @@ dependencies {
implementation "org.springframework.cloud:spring-cloud-starter-openfeign:3.1.0"
// JsonPath
implementation "com.jayway.jsonpath:json-path:2.5.0"
// Open Search
implementation "org.opensearch.client:spring-data-opensearch-starter:1.2.0"
implementation "org.opensearch.client:opensearch-rest-high-level-client:2.9.0"
implementation 'org.opensearch.client:opensearch-java:1.0.0'
implementation 'org.opensearch.client:opensearch-rest-client:1.3.4'
implementation "org.opensearch.client:spring-data-opensearch:1.2.0"
implementation 'org.springframework.data:spring-data-elasticsearch:5.0.0'




implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.2'

// easy random
testImplementation 'org.jeasy:easy-random-core:5.0.0'
Expand Down Expand Up @@ -168,4 +182,4 @@ dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
}
}
}
19 changes: 19 additions & 0 deletions src/docs/asciidoc/admin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,22 @@ operation::v1/admin/carousels[snippets='http-request,request-headers,response-fi
=== 케러셀 순서 수정 API [PATCH]

operation::v1/admin/carousels/order/update[snippets='http-request,request-headers,request-fields,http-response']

== Admin Hot Keyword APIs

- 인기 검색어 순위 조회 API [GET]
- 인기 검색어 변경 API [PUT]
- 검색어 검색 횟수 조회 API [GET]


=== 인기 검색어 순위 조회 API [GET]

operation::v1/admin/search/hot-keywords/rank[snippets='http-request,request-headers,response-fields,http-response']

=== 검색어 검색 횟수 조회 API [GET]

operation::v1/admin/search/hot-keywords[snippets='http-request,request-headers,request-parameters,response-fields,http-response']

=== 인기 검색어 변경 API [PUT]

operation::v1/admin/search/hot-keywords/rank/update[snippets='http-request,request-headers,request-fields,http-response']
32 changes: 17 additions & 15 deletions src/docs/asciidoc/search.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,25 @@
:operation-http-response-title: Example Response

== APIs
// - 자동 완성 API
- 자동 완성 API
- 검색 API
// - 최근 검색어 조회 API
// - 최근 검색어 단건 삭제 API
// - 최근 검색어 전체 삭제 API

// === 자동 완성 API [GET]
// operation::v1/search/auto[snippets='http-request,request-headers,request-parameters,http-response,response-fields']
=== 검색 API [GET] New
operation::v2/search/keyword[snippets='http-request,request-parameters,http-response,response-fields']

=== 검색 API [GET]
=== 검색 API [GET] Old (/v2 API 호출 실패 시 조회)
operation::v1/search/search[snippets='http-request,request-headers,request-parameters,http-response,response-fields']

// === 최근 검색어 조회 API [GET]
// operation::v1/search/keywords[snippets='http-request,request-headers,http-response,response-fields']
//
// === 최근 검색어 단건 삭제 API [DELETE]
// operation::v1/search/keywords/delete[snippets='http-request,request-headers,request-parameters,http-response']
//
// === 최근 검색어 전체 삭제 API [DELETE]
// operation::v1/search/keywords/deleteAll[snippets='http-request,request-headers,http-response']
=== 자동완성 검색어 추천 API [GET]
operation::v2/search/suggestions[snippets='http-request,request-parameters,http-response,response-fields']

== OpenSearch Query 테스트용 End Point

=== Index에 data추가 API [POST]
operation::v1/search-engine/document[snippets='http-request,request-fields,http-response,response-fields']

=== 빵 상품명으로 검색 테스트 API [GET]
operation::v1/search-engine/document/bread[snippets='http-request,request-parameters,http-response,response-fields']

=== 빵집명으로 검색 테스트 API [GET]
operation::v1/search-engine/document/bakery[snippets='http-request,request-parameters,http-response,response-fields']
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

import javax.annotation.PostConstruct;

import com.depromeet.breadmapbackend.global.security.domain.RoleType;
import com.depromeet.breadmapbackend.global.security.token.JwtToken;
import com.depromeet.breadmapbackend.global.security.token.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
Expand All @@ -19,7 +23,10 @@
@ConfigurationPropertiesScan
@SpringBootApplication
@EnableScheduling
//@RequiredArgsConstructor
public class BreadMapBackendApplication {

// private final JwtTokenProvider jwtTokenProvider;
@PostConstruct
public void started() {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
Expand All @@ -33,4 +40,13 @@ public static void main(String[] args) {
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

// @PostConstruct
// public PasswordEncoder passwordEncoder() {
// JwtToken adminUserForEventPost = jwtTokenProvider.createJwtToken("ADMIN_USER_FOR_EVENT_POST", RoleType.USER.getCode());
// System.out.println("passwordEncoder :: ================" + adminUserForEventPost.getAccessToken());
//
// return PasswordEncoderFactories.createDelegatingPasswordEncoder();
//
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import java.util.Set;
import java.util.stream.Collectors;

import com.depromeet.breadmapbackend.domain.search.dto.OpenSearchIndex;
import com.depromeet.breadmapbackend.domain.search.dto.keyword.BakeryLoadData;
import com.depromeet.breadmapbackend.domain.search.dto.keyword.BreadLoadData;
import com.depromeet.breadmapbackend.domain.search.events.OpenSearchEventPublisher;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -91,6 +95,7 @@ public class AdminBakeryServiceImpl implements AdminBakeryService {
private final S3Uploader s3Uploader;
private final SgisClient sgisClient;
private final ApplicationEventPublisher eventPublisher;
private final OpenSearchEventPublisher openSearchEventPublisher;
private final CustomSGISKeyProperties customSGISKeyProperties;
private final CustomAWSS3Properties customAWSS3Properties;
private final UpdateBakerySQSService updateBakerySQSService; // TODO : migrate to AOP
Expand Down Expand Up @@ -222,11 +227,11 @@ public BakeryAddDto addBakery(BakeryAddRequest request) {
if (bakery.getStatus().equals(BakeryStatus.POSTING)) {
if (pioneer != null) {
eventPublisher.publishEvent(
NoticeEventDto.builder()
.userId(pioneer.getId())
.contentId(bakery.getId())
.noticeType(NoticeType.REPORT_BAKERY_ADDED)
.build()
NoticeEventDto.builder()
.userId(pioneer.getId())
.contentId(bakery.getId())
.noticeType(NoticeType.REPORT_BAKERY_ADDED)
.build()
);
}
eventPublisher.publishEvent(
Expand All @@ -236,6 +241,8 @@ public BakeryAddDto addBakery(BakeryAddRequest request) {
.noticeType(NoticeType.BAKERY_ADDED)
.build()
);

openSearchEventPublisher.publishSaveBakery(new BakeryLoadData(bakery.getId(), bakery.getName(), bakery.getAddress(), bakery.getLongitude(), bakery.getLatitude()));
}

return BakeryAddDto.builder().bakeryId(bakery.getId()).build();
Expand All @@ -248,15 +255,23 @@ public void updateBakery(Long bakeryId, BakeryUpdateRequest request) {

List<String> images = getImagesIfExistsOrGetDefaultImage(request.getImages());

BakeryStatus status = request.getStatus();
if(status == BakeryStatus.POSTING) {
openSearchEventPublisher.publishSaveBakery(new BakeryLoadData(bakery.getId(), bakery.getName(), bakery.getAddress(), bakery.getLongitude(), bakery.getLatitude()));
} else if(status == BakeryStatus.UNPOSTING) {
openSearchEventPublisher.publishDeleteBakery(bakeryId);
}

bakery.update(request.getName(),
request.getAddress(), request.getDetailedAddress(), request.getLatitude(), request.getLongitude(),
request.getHours(),
request.getWebsiteURL(), request.getInstagramURL(), request.getFacebookURL(), request.getBlogURL(),
request.getPhoneNumber(), request.getCheckPoint(), request.getNewBreadTime(),
images,
request.getFacilityInfoList(), request.getStatus());
request.getFacilityInfoList(), status);

if (request.getProductList() != null && !request.getProductList().isEmpty()) { // TODO
openSearchEventPublisher.publishDeleteAllProducts(bakeryId);
for (BakeryUpdateRequest.ProductUpdateRequest productUpdateRequest : request.getProductList()) {
Product product;
if (productUpdateRequest.getProductId() == null) { // 새로운 product 일 때
Expand All @@ -273,6 +288,8 @@ public void updateBakery(Long bakeryId, BakeryUpdateRequest request) {
product.update(productUpdateRequest.getProductType(), productUpdateRequest.getProductName(),
productUpdateRequest.getPrice(), productUpdateRequest.getImage());
}

openSearchEventPublisher.publishSaveBread(new BreadLoadData(product.getId(), product.getName(), bakeryId, bakery.getName(), bakery.getAddress(), bakery.getLongitude(), bakery.getLatitude()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class CurationPushNotificationScheduler {
private final ApplicationEventPublisher eventPublisher;
private final CurationFeedRepository curationFeedRepository;

@Scheduled(cron = "0 14 * * * *")
@Scheduled(cron = "0 0 14 * * *")
@Transactional
public void publishCurationPushNotificationEvent() {
log.info("========================= Send Curation Notification =========================");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.depromeet.breadmapbackend.domain.admin.openSearch;

import com.depromeet.breadmapbackend.domain.admin.openSearch.dto.request.OpenSearchCreateIndexRequest;
import com.depromeet.breadmapbackend.domain.admin.openSearch.dto.response.OpenSearchCreateIndexResponse;
import com.depromeet.breadmapbackend.domain.search.OpenSearchService;
import com.depromeet.breadmapbackend.global.dto.ApiResponse;
import com.depromeet.breadmapbackend.global.exception.ValidationSequence;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.IOException;

@Validated(ValidationSequence.class)
@RestController
@RequestMapping("/v1/admin/search-engine")
@RequiredArgsConstructor
public class OpenSearchAdminController {
private final OpenSearchService openSearchService;

@PostMapping
@ResponseStatus(HttpStatus.OK)
public ApiResponse<OpenSearchCreateIndexResponse> createIndex(
@Valid @RequestBody OpenSearchCreateIndexRequest createIndexRequest) throws IOException {
return new ApiResponse<>(openSearchService.deleteAndCreateIndex(createIndexRequest.getIndexName().toLowerCase()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.depromeet.breadmapbackend.domain.admin.openSearch.dto;

import com.depromeet.breadmapbackend.domain.user.User;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class KeywordSearchDto {
private User user;
private String keyword;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.depromeet.breadmapbackend.domain.admin.openSearch.dto.request;

import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class OpenSearchCreateIndexRequest {
String indexName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.depromeet.breadmapbackend.domain.admin.openSearch.dto.response;

import lombok.Getter;

@Getter
public class OpenSearchCreateIndexResponse {

private String message;

public OpenSearchCreateIndexResponse(String message) {
this.message = message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public void updateEventPost(final EventCommand command, final Long managerId) {

final PostManagerMapper postManagerMapper = postAdminRepository.findPostManagerMapperById(managerId)
.orElseThrow(() -> new DaedongException(DaedongStatus.POST_NOT_FOUND));
final boolean beforePostStatus = postManagerMapper.isPosted();

final CarouselManager carouselManager =
carouselRepository.findByTargetIdAndCarouselType(postManagerMapper.getId(),
Expand All @@ -141,7 +142,7 @@ public void updateEventPost(final EventCommand command, final Long managerId) {
carouselManagerService.toggleCarousel(carouselManager.getId(), command.isCarousel());
carouselManager.updateBannerImage(command.bannerImage());

if (command.isPosted()) {
if (!beforePostStatus && command.isPosted()) {
eventPublisher.publishEvent(
NoticeEventDto.builder()
.contentId(postManagerMapper.getId())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.depromeet.breadmapbackend.domain.admin.search;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.depromeet.breadmapbackend.domain.admin.search.dto.HotKeywordResponse;
import com.depromeet.breadmapbackend.domain.admin.search.dto.HotKeywordUpdateRequest;
import com.depromeet.breadmapbackend.domain.admin.search.dto.KeywordStatResponse;
import com.depromeet.breadmapbackend.global.dto.ApiResponse;

import lombok.RequiredArgsConstructor;

/**
* AdminSearchKeywordController
*
* @author jaypark
* @version 1.0.0
* @since 11/10/23
*/

@RestController
@RequestMapping("/v1/admin/search/hot-keywords")
@RequiredArgsConstructor
public class AdminHotKeywordController {

private final AdminHotKeywordService adminHotKeywordService;

@GetMapping
ApiResponse<List<KeywordStatResponse>> getHotKeywordsByKeyword(
@RequestParam(name = "sortType", required = false, defaultValue = "THREE_MONTH") String sortType
) {
return new ApiResponse<>(
adminHotKeywordService.getHotKeywords(SortType.valueOf(sortType.toUpperCase()))
.stream()
.map(Mapper::of)
.toList()
);
}

@GetMapping("/rank")
ApiResponse<List<HotKeywordResponse>> getHotKeywords() {
return new ApiResponse<>(
adminHotKeywordService.getHotKeywordsRanking()
.stream()
.map(Mapper::of)
.toList()
);
}

@PutMapping("/rank")
@ResponseStatus(HttpStatus.ACCEPTED)
void updateHotKeywords(@RequestBody HotKeywordUpdateRequest request) {
adminHotKeywordService.updateHotKeywordsRanking(
request.HotKeywordList()
.stream()
.map(HotKeywordUpdateRequest.HotKeywordInfo::toEntity)
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.depromeet.breadmapbackend.domain.admin.search;

import java.util.List;

/**
* AdminHotKeywordService
*
* @author jaypark
* @version 1.0.0
* @since 11/10/23
*/
public interface AdminHotKeywordService {
List<Keyword> getHotKeywords(SortType sortType);

List<HotKeyword> getHotKeywordsRanking();

void updateHotKeywordsRanking(List<HotKeyword> hotKeywords);

}
Loading

0 comments on commit 9ad8d43

Please sign in to comment.