Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release #66

Merged
merged 10 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.dailyon.productservice.category.repository;

import com.dailyon.productservice.category.entity.Category;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -16,6 +18,8 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {

List<Category> findAllByOrderByNameAsc();

Page<Category> findAllByOrderByNameAsc(Pageable pageable);

List<Category> findCategoriesByNameContainsOrderByNameAsc(String name);

@Query(nativeQuery = true, value =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public ReadChildrenCategoryListResponse readLeafCategories() {
}

public ReadCategoryPageResponse readCategoryPages(Pageable pageable) {
return ReadCategoryPageResponse.fromEntity(categoryRepository.findAll(pageable));
return ReadCategoryPageResponse.fromEntity(categoryRepository.findAllByOrderByNameAsc(pageable));
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.dailyon.productservice.category.entity.Category;
import com.dailyon.productservice.product.dto.response.ReadBestProductListResponse;
import com.dailyon.productservice.product.dto.response.ReadNewProductListResponse;
import com.dailyon.productservice.product.dto.response.ReadProductDetailResponse;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand Down Expand Up @@ -54,8 +55,12 @@ public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(
Jackson2JsonRedisSerializer<ReadBestProductListResponse> bestProductVOJackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<>(ReadBestProductListResponse.class);

Jackson2JsonRedisSerializer<ReadProductDetailResponse> auctionProductVOJackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<>(ReadProductDetailResponse.class);

newProductVOJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
bestProductVOJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
auctionProductVOJackson2JsonRedisSerializer.setObjectMapper(objectMapper);

return (builder -> builder
.withCacheConfiguration(
Expand All @@ -82,6 +87,18 @@ public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(
.fromSerializer(bestProductVOJackson2JsonRedisSerializer)
)
)
.withCacheConfiguration(
"auctionProducts",
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1))
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer())
)
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(auctionProductVOJackson2JsonRedisSerializer)
)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public ErrorResponse validException(BindException e) {
}

@ExceptionHandler(NotExistsException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse notExistsException(NotExistsException e) {
return ErrorResponse.builder()
.message(e.getMessage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ ResponseEntity<ReadProductPageResponse> readProductPage(
@RequestParam(required = false) Long categoryId,
@RequestParam ProductType type,
@RequestParam(required = false) String query,
@PageableDefault(
size = 5,
sort = {"updatedAt"},
direction = Sort.Direction.DESC
) Pageable pageable
@RequestParam int page,
@RequestParam int size,
@RequestParam String sort,
@RequestParam String direction
) {
return ResponseEntity.status(HttpStatus.OK).body(
productFacade.readProductPage(brandId, categoryId, type, query, pageable)
productFacade.readProductPage(
brandId, categoryId, type, query,
page, size, sort, direction
)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.dailyon.productservice.product.dto.response.*;
import com.dailyon.productservice.product.facade.ProductFacade;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Expand All @@ -20,6 +21,10 @@ ResponseEntity<ReadProductDetailResponse> readProductDetail(@PathVariable Long p
return ResponseEntity.status(HttpStatus.OK).body(productFacade.readProductDetail(productId));
}

@GetMapping("/auctions/id/{productId}")
ResponseEntity<ReadProductDetailResponse> readAuctionProductDetail(@PathVariable Long productId) {
return ResponseEntity.status(HttpStatus.OK).body(productFacade.readAuctionProductDetail(productId));
}
/**
* 쇼핑몰 화면에서 무한 스크롤 위한 조회 api
* @param lastVal 최초 호출 시 direction이 asc면 0, desc면 큰 값
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
public class ReadProductAdminResponse {
private Long id;
private Long brandId;
private String brandName;
private Long categoryId;
private String categoryName;
private String name;
private Gender gender;
private Integer price;
Expand All @@ -33,7 +35,9 @@ public static ReadProductAdminResponse fromEntity(Product product) {
return ReadProductAdminResponse.builder()
.id(product.getId())
.brandId(product.getBrand().getId())
.brandName(product.getBrand().getName())
.categoryId(product.getCategory().getId())
.categoryName(product.getCategory().getName())
.name(product.getName())
.gender(product.getGender())
.price(product.getPrice())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public ReadProductDetailResponse readProductDetail(Long productId) {
return productService.readProductDetail(productId);
}

@Cacheable(value = "auctionProducts", key = "#productId", unless = "#result == null")
public ReadProductDetailResponse readAuctionProductDetail(Long productId) {
return productService.readProductDetail(productId);
}

public ReadProductSliceResponse readProductSlice(
String lastVal, Long brandId, Long categoryId, Gender gender, ProductType productType,
Integer lowPrice, Integer highPrice, String query, String sort, String direction
Expand All @@ -91,8 +96,14 @@ public ReadOOTDSearchSliceResponse searchFromOOTD(Long lastId, String query) {
return productService.searchFromOOTD(lastId, query);
}

public ReadProductPageResponse readProductPage(Long brandId, Long categoryId, ProductType type, String query, Pageable pageable) {
return productService.readProductPage(brandId, categoryId, type, query, pageable);
public ReadProductPageResponse readProductPage(
Long brandId, Long categoryId, ProductType type, String query,
int page, int size, String sort, String direction
) {
return productService.readProductPage(
brandId, categoryId, type, query,
page, size, sort, direction
);
}

@Cacheable(value = "newProducts", unless = "#result == null")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Slice<Product> findProductSlice(
);

Page<Product> findProductPage(
Long brandId, List<Category> childCategories,
ProductType type, String query, Pageable pageable
Long brandId, List<Category> childCategories, ProductType type, String query,
int page, int size, String sort, String direction
);

Slice<Product> searchProductsFromOOTD(Long lastId, String query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import com.dailyon.productservice.common.enums.ProductType;
import com.dailyon.productservice.product.entity.Product;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -73,10 +71,11 @@ public Slice<Product> findProductSlice(

@Override
public Page<Product> findProductPage(
Long brandId, List<Category> childCategories,
ProductType type, String query, Pageable pageable
Long brandId, List<Category> childCategories, ProductType type, String query,
int page, int size, String sort, String direction
) {
PathBuilder<Product> entityPath = new PathBuilder<>(Product.class, "product");
Pageable pageable = PageRequest.of(page, size);

BooleanBuilder booleanBuilder = new BooleanBuilder();
if(query != null) {
booleanBuilder.and(nameContains(query).or(codeContains(query)));
Expand All @@ -90,14 +89,10 @@ public Page<Product> findProductPage(
.and(booleanBuilder)
.and(productTypeEq(type))
)
.orderBy(orderSpecifier(sort, direction))
.offset(pageable.getOffset())
.limit(pageable.getPageSize());
for(Sort.Order order: pageable.getSort()) {
indexQuery.orderBy(new OrderSpecifier(
order.isAscending() ? Order.ASC : Order.DESC,
entityPath.get(order.getProperty())
));
}

List<Long> indexes = indexQuery.fetch();
if(indexes.isEmpty()) {
return new PageImpl<>(new ArrayList<>(), pageable, 0);
Expand All @@ -111,14 +106,9 @@ public Page<Product> findProductPage(
.leftJoin(product.describeImages, describeImage).fetchJoin()
.leftJoin(product.productStocks, productStock).fetchJoin()
.leftJoin(product.reviewAggregate, reviewAggregate).fetchJoin()
.orderBy(orderSpecifier(sort, direction))
.where(product.id.in(indexes));

for(Sort.Order order: pageable.getSort()) {
resultQuery.orderBy(new OrderSpecifier(
order.isAscending() ? Order.ASC : Order.DESC,
entityPath.get(order.getProperty())
));
}
List<Product> result = resultQuery.fetch();

JPAQuery<Long> countQuery = jpaQueryFactory
Expand Down Expand Up @@ -166,11 +156,11 @@ public Slice<Product> searchProductsFromOOTD(Long lastId, String query) {
}

private BooleanExpression brandIdEq(Long brandId) {
return brandId == null ? null : brand.id.eq(brandId);
return brandId == null ? null : product.brand.id.eq(brandId);
}

private BooleanExpression categoryIn(List<Category> childCategories) {
return childCategories == null ? null : category.in(childCategories);
return childCategories == null ? null : product.category.in(childCategories);
}

private BooleanExpression genderEq(Gender gender) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,19 @@ public Slice<Product> readProductSlice(
}

public ReadProductPageResponse readProductPage(
Long brandId, Long categoryId, ProductType type,
String query, Pageable pageable
Long brandId, Long categoryId, ProductType type, String query,
int page, int size, String sort, String direction
) {
List<Category> childCategories = null;
if(categoryId != null) {
childCategories = categoryRepository.findAllChildCategories(categoryId);
}
return ReadProductPageResponse.fromEntity(
productRepository.findProductPage(brandId, childCategories, type, query, pageable));
productRepository.findProductPage(
brandId, childCategories, type, query,
page, size, sort, direction
)
);
}

public ReadOOTDSearchSliceResponse searchFromOOTD(Long lastId, String query) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
public class BestProductVO implements Serializable, Comparable<BestProductVO> {
private Long id;
private String brandName;
private Long categoryId;
private String categoryName;
private Integer price;
private String name;
Expand All @@ -25,6 +26,7 @@ public static BestProductVO create(Product product, ProductRankResponse rank) {
return BestProductVO.builder()
.id(product.getId())
.brandName(product.getBrand().getName())
.categoryId(product.getCategory().getId())
.categoryName(product.getCategory().getName())
.price(product.getPrice())
.name(product.getName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public class NewProductVO implements Serializable {
private Long id;
private String brandName;
private Long categoryId;
private String categoryName;
private Integer price;
private String name;
Expand All @@ -23,6 +24,7 @@ public static NewProductVO fromEntity(Product product) {
return NewProductVO.builder()
.id(product.getId())
.brandName(product.getBrand().getName())
.categoryId(product.getCategory().getId())
.categoryName(product.getCategory().getName())
.price(product.getPrice())
.name(product.getName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void updateBrandControllerFail1() throws Exception {
);

// then
resultActions.andExpect(MockMvcResultMatchers.status().isBadRequest());
resultActions.andExpect(MockMvcResultMatchers.status().isNotFound());
}

@Test
Expand Down Expand Up @@ -171,7 +171,7 @@ void deleteBrandFail1() throws Exception {
);

resultActions
.andExpect(MockMvcResultMatchers.status().isBadRequest())
.andExpect(MockMvcResultMatchers.status().isNotFound())
.andExpect(MockMvcResultMatchers.jsonPath("$.message").value(NotExistsException.BRAND_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void createCategoryFail2() throws Exception {

// then
resultActions
.andExpect(MockMvcResultMatchers.status().isBadRequest());
.andExpect(MockMvcResultMatchers.status().isNotFound());
}

@Test
Expand Down Expand Up @@ -225,7 +225,7 @@ void deleteCategoryFail() throws Exception {

// then
resultActions
.andExpect(MockMvcResultMatchers.status().isBadRequest())
.andExpect(MockMvcResultMatchers.status().isNotFound())
.andExpect(MockMvcResultMatchers.jsonPath("$.message")
.value(NotExistsException.CATEGORY_NOT_FOUND));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void createProductSizeFail1() throws Exception {
);

// then
resultActions.andExpect(MockMvcResultMatchers.status().isBadRequest());
resultActions.andExpect(MockMvcResultMatchers.status().isNotFound());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ void searchProductsFromOOTDTest() {
void readProductPage() {
// given, when
ReadProductPageResponse response = productService.readProductPage(
null, null, ProductType.valueOf("NORMAL"), null, PageRequest.of(0, 8)
null, null, ProductType.valueOf("NORMAL"), null,
0, 5, "updatedAt", "desc"
);

// then
Expand Down