diff --git a/order-service/src/docs/asciidoc/api-docs.adoc b/order-service/src/docs/asciidoc/api-docs.adoc index fc03fa9..1814c35 100644 --- a/order-service/src/docs/asciidoc/api-docs.adoc +++ b/order-service/src/docs/asciidoc/api-docs.adoc @@ -83,7 +83,11 @@ operation::prevOrder-get-BindException[snippets='curl-request,http-request,http- === 주문 내역 페이지 operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields'] +=== 장바구니 상품 추가 +operation::add-item-to-basket[snippets='curl-request,http-request,http-response,request-headers,request-body,request-fields'] +=== 장바구니 내역 가져오기 +operation::fetch-order[snippets='curl-request,http-request,http-response,request-headers,response-fields'] - -operation::add-item-to-basket[snippets='curl-request,http-request,http-response,request-headers,request-body,request-fields'] \ No newline at end of file +=== 주문하기 +operation::save-order[snippets='curl-request,http-request,http-response,request-headers'] \ No newline at end of file diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java index e002ef8..70f42de 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/dto/FetchOrderDto.java @@ -1,38 +1,27 @@ package com.justpickup.orderservice.domain.order.dto; import com.justpickup.orderservice.domain.order.entity.Order; -import com.justpickup.orderservice.domain.order.entity.OrderStatus; import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; -import com.justpickup.orderservice.domain.orderItem.entity.OrderItem; import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @Getter @NoArgsConstructor +@AllArgsConstructor public class FetchOrderDto { private Long id; private Long userId; - private String userName; - - private Long userCouponId; - private Long orderPrice; private Long storeId; - private LocalDateTime orderTime; - - private Long usedPoint; - - private OrderStatus orderStatus; - private List orderItemDtoList; diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java new file mode 100644 index 0000000..cba4a71 --- /dev/null +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderSender.java @@ -0,0 +1,69 @@ +package com.justpickup.orderservice.domain.order.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.justpickup.orderservice.domain.order.entity.Order; +import com.justpickup.orderservice.domain.order.entity.OrderStatus; +import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +@Service +@Slf4j +@RequiredArgsConstructor +public class OrderSender { + + private final KafkaTemplate kafkaTemplate; + + public void orderPlaced( KafkaSendOrderDto kafkaSendOrderDto) throws Exception{ + ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); + String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto); + kafkaTemplate.send("orderPlaced", jsonInString); + log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto); + } + + @NoArgsConstructor + @Data + @AllArgsConstructor + @Builder + static class KafkaSendOrderDto{ + private Long id; + + private Long userId; + + private String userName; + + private Long userCouponId; + + private Long orderPrice; + + private Long storeId; + + private LocalDateTime orderTime; + + private Long usedPoint; + + private OrderStatus orderStatus; + + private List orderItemDtoList; + + // == 생성 메소드 == // + public static KafkaSendOrderDto createPrimitiveField(Order order) { + return KafkaSendOrderDto.builder() + .id(order.getId()) + .userId(order.getUserId()) + .userCouponId(order.getUserCouponId()) + .orderPrice(order.getOrderPrice()) + .orderTime(order.getOrderTime()) + .storeId(order.getStoreId()) + .usedPoint(order.getUsedPoint()) + .orderStatus(order.getOrderStatus()) + .build(); + } + } +} diff --git a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java index 4e847cd..b2e8b22 100644 --- a/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java +++ b/order-service/src/main/java/com/justpickup/orderservice/domain/order/service/OrderServiceImpl.java @@ -1,10 +1,5 @@ package com.justpickup.orderservice.domain.order.service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.justpickup.orderservice.domain.order.dto.FetchOrderDto; import com.justpickup.orderservice.domain.order.dto.OrderDto; import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition; @@ -29,11 +24,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.SliceImpl; import org.springframework.data.support.PageableExecutionUtils; -import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -50,7 +43,9 @@ public class OrderServiceImpl implements OrderService { private final OrderRepositoryCustom orderRepositoryCustom; private final StoreClient storeClient; private final UserClient userClient; - private final KafkaTemplate kafkaTemplate; + private final OrderSender orderSender; + + @Override public List findOrderMain(OrderSearchCondition condition, Long storeId) { @@ -154,59 +149,13 @@ public class OrderServiceImpl implements OrderService { .orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다.")) .setOrderStatus(OrderStatus.PLACED); try{ - send("orderPlaced",KafkaSendOrderDto.createPrimitiveField(order)); + orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order)); }catch (Exception ex){ throw new OrderException(ex.getMessage()); } } - public void send(String topic, KafkaSendOrderDto kafkaSendOrderDto) throws Exception{ - ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); - String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto); - kafkaTemplate.send(topic, jsonInString); - log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto); - } - @NoArgsConstructor - @Data - @AllArgsConstructor - @Builder - static class KafkaSendOrderDto{ - private Long id; - - private Long userId; - - private String userName; - - private Long userCouponId; - - private Long orderPrice; - - private Long storeId; - -// @JsonDeserialize(using = LocalDateTimeDeserializer.class) - private LocalDateTime orderTime; - - private Long usedPoint; - - private OrderStatus orderStatus; - - private List orderItemDtoList; - - // == 생성 메소드 == // - public static KafkaSendOrderDto createPrimitiveField(Order order) { - return KafkaSendOrderDto.builder() - .id(order.getId()) - .userId(order.getUserId()) - .userCouponId(order.getUserCouponId()) - .orderPrice(order.getOrderPrice()) - .orderTime(order.getOrderTime()) - .storeId(order.getStoreId()) - .usedPoint(order.getUsedPoint()) - .orderStatus(order.getOrderStatus()) - .build(); - } - } } diff --git a/order-service/src/test/java/com/justpickup/orderservice/domain/order/service/OrderSenderTest.java b/order-service/src/test/java/com/justpickup/orderservice/domain/order/service/OrderSenderTest.java new file mode 100644 index 0000000..1358d03 --- /dev/null +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/service/OrderSenderTest.java @@ -0,0 +1,105 @@ +package com.justpickup.orderservice.domain.order.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.justpickup.orderservice.domain.order.entity.OrderStatus; +import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto; +import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.SendResult; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.util.concurrent.ListenableFuture; + +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(SpringExtension.class) +@EnableKafka +@DirtiesContext +@EmbeddedKafka(topics = {"orderPlaced"}) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class OrderSenderTest { + + private final String TEST_TOPIC = "orderPlaced"; + + private Consumer consumer; + private KafkaTemplate producer; + + @Autowired + private EmbeddedKafkaBroker embeddedKafkaBroker; + + + @BeforeEach + void setup() { + System.out.println("beforeAll"); + producer = configureProducer(); + consumer = configureConsumer(); + + + } + + private Consumer configureConsumer() { + Map consumerProps = KafkaTestUtils.consumerProps("testGroup", "true", embeddedKafkaBroker); + consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + Consumer consumer = new DefaultKafkaConsumerFactory(consumerProps) + .createConsumer(); + consumer.subscribe(Collections.singleton(TEST_TOPIC)); + return consumer; + } + + + private KafkaTemplate configureProducer() { + Map producerProps = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker)); + return new KafkaTemplate <>( new DefaultKafkaProducerFactory<>(producerProps)); + } + + + + @Test + void sendOrderPlaced() throws Exception{ + //given + ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); + OrderSender.KafkaSendOrderDto kafkaSendOrderDto = new OrderSender.KafkaSendOrderDto( + 1L,2L,"주문아이디",1L,12000L,2L, LocalDateTime.now(),3000L, OrderStatus.PLACED, + List.of( + OrderItemDto.of(1L,300L,3000L,2L, + List.of(new OrderItemOptionDto(2L) + ,new OrderItemOptionDto(3L)) + ) + ) + ); + String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto); + + //when + ListenableFuture> orderPlaced = producer.send("orderPlaced", jsonInString); + System.out.println(orderPlaced.get().toString()); + //then + + ConsumerRecord singleRecord = KafkaTestUtils.getSingleRecord(consumer, TEST_TOPIC); + assertThat(singleRecord).isNotNull(); + assertThat(singleRecord.value()).isEqualTo(jsonInString); + + } + + +} \ No newline at end of file diff --git a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java index eed18ce..d05625a 100644 --- a/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java +++ b/order-service/src/test/java/com/justpickup/orderservice/domain/order/web/OrderCustomerApiControllerTest.java @@ -176,10 +176,39 @@ class OrderCustomerApiControllerTest { @DisplayName("장바구니 정보 조회_성공") void fetchOrder() throws Exception{ //Given + FetchOrderDto fetchOrderDto = + new FetchOrderDto(2L,2L,12000L,2L + ,List.of( + OrderItemDto.of(1L,300L,3000L,2L, + List.of(new OrderItemOptionDto(2L) + ,new OrderItemOptionDto(3L)) + ) + ) + ); + given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto); //When + ResultActions actions = mockMvc.perform(get(url + "/orders") + .header("user-id", "2") + ); + //Then + actions.andExpect(status().isOk()) + .andDo(print()) + .andDo(document("fetch-order", + requestHeaders(headerWithName("user-id").description("유저 고유번호")), + responseFields( + fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data.storeId").description("매장 고유번호"), + fieldWithPath("data.totalPrice").description("총 합계"), + fieldWithPath("data._orderItemDtos[*].itemId").description("상품 고유번호"), + fieldWithPath("data._orderItemDtos[*].price").description("상품 가격"), + fieldWithPath("data._orderItemDtos[*].count").description("상품 갯수"), + fieldWithPath("data._orderItemDtos[*].itemOptionIds[*]").description("아이템 옵션들") + ))); + } @@ -189,8 +218,15 @@ class OrderCustomerApiControllerTest { //Given //When - + ResultActions actions = mockMvc.perform(post(url + "/orders") + .header("user-id", "2") + ); //Then + actions.andExpect(status().isCreated()) + .andDo(print()) + .andDo(document("save-order", + requestHeaders(headerWithName("user-id").description("유저 고유번호")) + )); }