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

Get orders by Customer Id #537

Merged
merged 7 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
25 changes: 25 additions & 0 deletions order-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,30 @@
* Actuator Endpoint: http://localhost:18282/order-service/actuator
* Catalog Service : http://localhost:18080/catalog-service/swagger-ui.html

## Running only this Service Locally - Tips

To run only the Order Service locally with clean logs, you can follow these steps:



1.start the Kafka and Postgres servers by using below command(You should be inside appropriate directory and docker setup should be done :- ) :
```shell
docker compose up kafka postgres
```
2.In IntelIj Open Modify Run Configuration from Main class:
`com.example.orderservice.OrderServiceApplication`
Set the Environment variable value to
```text
SPRING_PROFILES_ACTIVE=local
```

3.In case local profile doesn't due to any issues possible not able to connect to postgresDB
Modify the Environment Variable Value as below this brings application up by connecting to H2 database.
```text
SPRING_PROFILES_ACTIVE=local1
```



### Notes
* KafkaStream DeadLetter is configured in `KafkaStreamsConfig.java`
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,7 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.

package com.example.orderservice.entities;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.Objects;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -51,6 +43,12 @@ public class OrderItem {
@Column(columnDefinition = "NUMERIC(19,2)")
private BigDecimal productPrice;

@Transient private BigDecimal price;

public BigDecimal getPrice() {
return productPrice.multiply(new BigDecimal(quantity));
}

@ManyToOne(fetch = FetchType.LAZY)
@ToString.Exclude
private Order order;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.
import com.example.orderservice.entities.OrderItem;
import com.example.orderservice.model.request.OrderItemRequest;
import com.example.orderservice.model.request.OrderRequest;
import com.example.orderservice.model.response.OrderItemResponse;
import com.example.orderservice.model.response.OrderResponse;
import org.mapstruct.AfterMapping;
import org.mapstruct.DecoratedWith;
import org.mapstruct.Mapper;
Expand Down Expand Up @@ -43,6 +45,7 @@ public interface OrderMapper {

@Mapping(target = "id", ignore = true)
@Mapping(target = "order", ignore = true)
@Mapping(target = "price", ignore = true)
OrderItem orderItemRequestToOrderItem(OrderItemRequest orderItemRequest);

@AfterMapping
Expand All @@ -65,4 +68,11 @@ default void addOrderItemRequestToOrderEntity(
@Mapping(target = "lastModifiedBy", ignore = true)
@Mapping(target = "lastModifiedDate", ignore = true)
void updateOrderFromOrderRequest(OrderRequest orderRequest, @MappingTarget Order order);

@Mapping(source = "id", target = "orderId")
OrderResponse toResponse(Order order);

@Mapping(target = "itemId", source = "id")
@Mapping(target = "productId", source = "productCode")
OrderItemResponse orderItemToOrderItemResponse(OrderItem orderItem);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/***
<p>
Licensed under MIT License Copyright (c) 2023 Raja Kolli.
</p>
***/

package com.example.orderservice.model.response;

import java.math.BigDecimal;

public record OrderItemResponse(
Long itemId, String productId, int quantity, BigDecimal productPrice, BigDecimal price) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/***
<p>
Licensed under MIT License Copyright (c) 2023 Raja Kolli.
</p>
***/

package com.example.orderservice.model.response;

import java.time.LocalDateTime;
import java.util.List;

public record OrderResponse(
Long orderId,
Long customerId,
String status,
String source,
LocalDateTime createdDate,
List<OrderItemResponse> items) {}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("select o from Order o join fetch o.items oi where o.id = :id")
Optional<Order> findOrderById(@Param("id") Long id);

@Query(
value = "select o from Order o join fetch o.items oi where o.customerId = :customerId",
countQuery = "select count(o) from Order o where o.customerId=:customerId")
Page<Order> findByCustomerId(@Param("customerId") Long customerId, Pageable pageable);

@Modifying
@Transactional
@Query("update Order o set o.status =:status, o.source =:source where o.id = :id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.
import com.example.orderservice.mapper.OrderMapper;
import com.example.orderservice.model.request.OrderItemRequest;
import com.example.orderservice.model.request.OrderRequest;
import com.example.orderservice.model.response.OrderResponse;
import com.example.orderservice.model.response.PagedResult;
import com.example.orderservice.repositories.OrderRepository;
import java.util.List;
Expand Down Expand Up @@ -124,4 +125,27 @@ public Optional<Order> findById(Long id) {
public Optional<OrderDto> findOrderByIdAsDto(Long id) {
return orderRepository.findOrderById(id).map(this.orderMapper::toDto);
}

public PagedResult<OrderResponse> getOrdersByCustomerId(Long customerId, Pageable pageable) {
var ordersList = orderRepository.findByCustomerId(customerId, pageable);
List<CompletableFuture<OrderResponse>> completableFutureList =
ordersList.stream()
.map(
order ->
CompletableFuture.supplyAsync(
() -> this.orderMapper.toResponse(order)))
.toList();
// Joining all completeable future to get DTOs
List<OrderResponse> orderListDto =
completableFutureList.stream().map(CompletableFuture::join).toList();
return new PagedResult<>(
orderListDto,
ordersList.getTotalElements(),
ordersList.getNumber(),
ordersList.getTotalPages(),
ordersList.isFirst(),
ordersList.isLast(),
ordersList.hasNext(),
ordersList.hasPrevious());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.

import com.example.common.dtos.OrderDto;
import com.example.orderservice.model.request.OrderRequest;
import com.example.orderservice.model.response.OrderResponse;
import com.example.orderservice.model.response.PagedResult;
import com.example.orderservice.services.OrderGeneratorService;
import com.example.orderservice.services.OrderKafkaStreamService;
Expand All @@ -18,6 +19,7 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.
import java.net.URI;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand Down Expand Up @@ -131,4 +133,10 @@ public List<OrderDto> all(
int pageSize) {
return orderKafkaStreamService.getAllOrders(pageNo, pageSize);
}

@GetMapping("customer/{id}")
public ResponseEntity<PagedResult<OrderResponse>> ordersByCustomerId(
rajadilipkolli marked this conversation as resolved.
Show resolved Hide resolved
@PathVariable Long id, Pageable pageable) {
return ResponseEntity.ok(orderService.getOrdersByCustomerId(id, pageable));
}
}
17 changes: 17 additions & 0 deletions order-service/src/main/resources/application-h2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
spring:
cloud:
config:
enabled: false
discovery:
enabled: false
datasource:
url: jdbc:h2:file:/data/demo
username: sa
password: password
driverClassName: org.h2.Driver
jpa:
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
config:
import: optional:configserver:${CONFIG_SERVER:http://localhost:8888}/
application:
catalog-service-url: http://localhost:18080/catalog-service
3 changes: 3 additions & 0 deletions order-service/src/main/resources/application-local.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ spring.datasource.url=jdbc:postgresql://localhost:5432/appdb
spring.datasource.username=appuser
spring.datasource.password=secret

spring.cloud.config.enabled=false
rajadilipkolli marked this conversation as resolved.
Show resolved Hide resolved
spring.cloud.discovery.enabled=false

application.catalog-service-url=http://localhost:18080/catalog-service

spring.config.import=optional:configserver:${CONFIG_SERVER:http://localhost:8888}/
1 change: 0 additions & 1 deletion order-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ server:
servlet:
contextPath: /${spring.application.name}
forward-headers-strategy: framework

spring:
application:
name: order-service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ Licensed under MIT License Copyright (c) 2023 Raja Kolli.

import static com.example.orderservice.utils.AppConstants.PROFILE_TEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User Assertions4J


import com.example.orderservice.common.PostGreSQLContainer;
import com.example.orderservice.entities.Order;
import com.example.orderservice.util.TestData;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
Expand All @@ -35,8 +35,8 @@ class OrderRepositoryTest {
@Autowired private OrderRepository orderRepository;
@Autowired private OrderItemRepository orderItemRepository;

@AfterEach
void tearDown() {
@BeforeEach
void setUp() {
this.orderItemRepository.deleteAllInBatch();
this.orderRepository.deleteAllInBatch();
}
Expand Down Expand Up @@ -66,4 +66,18 @@ void findAllOrders() {
assertThat(page.getNumberOfElements()).isEqualTo(5);
assertThat(page.getContent()).isNotEmpty().hasSize(5);
}

@Test
@DisplayName("getOrdersByCustomerIdTest")
void getOrdersByCustomerIdTest() {
List<Order> orderList = new ArrayList<>();
for (int i = 0; i < 15; i++) {
orderList.add(TestData.getOrder());
}
this.orderRepository.saveAll(orderList);
Pageable pageable = PageRequest.of(0, 1);
Page<Order> ordersPage = orderRepository.findByCustomerId(1L, pageable);
assertEquals(15, ordersPage.getTotalPages());
assertEquals(15, ordersPage.getTotalElements());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static Order getOrder() {
OrderItem orderItem = new OrderItem();
orderItem.setProductCode("Product1");
orderItem.setQuantity(10);
orderItem.setProductPrice(BigDecimal.TEN);
orderItem.setProductPrice(new BigDecimal("10.1"));
OrderItem orderItem1 = new OrderItem();
orderItem1.setProductCode("Product2");
orderItem1.setQuantity(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ Licensed under MIT License Copyright (c) 2021-2023 Raja Kolli.
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;

class OrderControllerIT extends AbstractIntegrationTest {

@Autowired private OrderRepository orderRepository;

private List<Order> orderList = null;
private OrderItem orderItem;

@BeforeEach
void setUp() {
Expand Down Expand Up @@ -178,7 +182,7 @@ void shouldUpdateOrder() throws Exception {
.andExpect(jsonPath("$.status", is("NEW")))
.andExpect(jsonPath("$.items.size()", is(2)))
.andExpect(jsonPath("$.items[0].quantity", is(110)))
.andExpect(jsonPath("$.items[0].price", is(1100)))
.andExpect(jsonPath("$.items[0].price", is(1111.0)))
.andExpect(jsonPath("$.items[1].quantity", is(100)))
.andExpect(jsonPath("$.items[1].price", is(100)));
}
Expand All @@ -191,4 +195,31 @@ void shouldDeleteOrder() throws Exception {
.perform(delete("/api/orders/{id}", order.getId()))
.andExpect(status().isAccepted());
}

@Test
@Disabled
void shouldFindOrdersByCustomersId() throws Exception {
OrderItem orderItem = orderList.get(0).getItems().get(0);

Pageable pageable = PageRequest.of(0, 1);
mockMvc.perform(
get("/api/orders/customer/{id}", orderList.get(0).getCustomerId())
.queryParam("page", "0")
.queryParam("size", "1"))
.andExpect(status().isOk())
.andExpect(
jsonPath(
"$.data[0].customerId",
is(orderList.get(0).getCustomerId()),
Long.class))
.andExpect(jsonPath("$.totalElements", is(orderList.size())))
.andExpect(
jsonPath(
"$.data[0].items[0].price",
is(
orderItem
.getProductPrice()
.multiply(new BigDecimal(orderItem.getQuantity()))),
BigDecimal.class));
}
}