package com.ecommerce.order.order.representation; import com.ecommerce.order.order.OrderRepository; import com.ecommerce.order.order.model.Order; import com.ecommerce.order.sdk.representation.order.OrderRepresentation; import com.ecommerce.order.sdk.representation.order.OrderSummaryRepresentation; import com.ecommerce.shared.jackson.DefaultObjectMapper; import com.ecommerce.shared.utils.PagedResource; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Map; import static com.google.common.collect.ImmutableMap.of; import static com.google.common.collect.Maps.newHashMap; @Slf4j @Component public class OrderRepresentationService { private static final String SELECT_SQL = "SELECT JSON_CONTENT FROM ORDER_SUMMARY LIMIT :limit OFFSET :offset;"; private static final String COUNT_SQL = "SELECT COUNT(1) FROM ORDER_SUMMARY;"; private final OrderRepository orderRepository; private final NamedParameterJdbcTemplate jdbcTemplate; private final DefaultObjectMapper objectMapper; public OrderRepresentationService(OrderRepository orderRepository, NamedParameterJdbcTemplate jdbcTemplate, DefaultObjectMapper objectMapper) { this.orderRepository = orderRepository; this.jdbcTemplate = jdbcTemplate; this.objectMapper = objectMapper; } @Transactional(readOnly = true) public OrderRepresentation byId(String id) { Order order = orderRepository.byId(id); return order.toRepresentation(); } @Transactional(readOnly = true) public PagedResource<OrderSummaryRepresentation> listOrders(int pageIndex, int pageSize) { MapSqlParameterSource parameters = new MapSqlParameterSource(); parameters.addValue("limit", pageSize); parameters.addValue("offset", (pageIndex - 1) * pageSize); List<OrderSummaryRepresentation> products = jdbcTemplate.query(SELECT_SQL, parameters, (rs, rowNum) -> objectMapper.readValue(rs.getString("JSON_CONTENT"), OrderSummaryRepresentation.class) ); int total = jdbcTemplate.queryForObject(COUNT_SQL, newHashMap(), Integer.class); return PagedResource.of(total, pageIndex, products); } @Transactional public void cqrsSync(String id) { Order order = orderRepository.byId(id); OrderSummaryRepresentation summary = order.toSummary(); String sql = "INSERT INTO ORDER_SUMMARY (ID, JSON_CONTENT) VALUES (:id, :json) " + "ON DUPLICATE KEY UPDATE JSON_CONTENT=:json;"; Map<String, String> paramMap = of("id", summary.getId(), "json", objectMapper.writeValueAsString(summary)); jdbcTemplate.update(sql, paramMap); log.info("Order[{}] summary synced due to CQRS.", id); } }