diff --git a/cart-spring-boot/pom.xml b/cart-spring-boot/pom.xml index b573309..7589b49 100644 --- a/cart-spring-boot/pom.xml +++ b/cart-spring-boot/pom.xml @@ -1,142 +1,160 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - com.redhat.coolstore - cart - 1.0.0-SNAPSHOT - jar + com.redhat.coolstore + cart + 1.0.0-SNAPSHOT + jar - cart-service + cart-service - - org.springframework.boot - spring-boot-starter-parent - 1.4.2.RELEASE - + + org.springframework.boot + spring-boot-starter-parent + 1.4.2.RELEASE + - - - - org.springframework.cloud - spring-cloud-dependencies - Camden.SR2 - pom - import - - - + + + + org.springframework.cloud + spring-cloud-dependencies + Camden.SR2 + pom + import + + + org.infinispan + infinispan-bom + ${version.org.infinispan} + pom + import + + + - - UTF-8 - UTF-8 - 1.8 - com.redhat.coolstore.CartServiceApplication - + + UTF-8 + UTF-8 + 1.8 + com.redhat.coolstore.CartServiceApplication + 6.3.1.Final-redhat-1 + - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-jersey - + + org.springframework.boot + spring-boot-starter-jersey + - - org.springframework.boot - spring-boot-starter-actuator - + + org.springframework.boot + spring-boot-starter-actuator + - - org.springframework.cloud - spring-cloud-starter-feign - - - com.sun.jersey - jersey-client - - - + + org.springframework.cloud + spring-cloud-starter-feign + + + com.sun.jersey + jersey-client + + + - - org.springframework.boot - spring-boot-starter-tomcat - provided - + + org.springframework.boot + spring-boot-starter-tomcat + provided + - - - org.springframework.boot - spring-boot-starter-test - test - - + + org.infinispan + infinispan-core + - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - io.fabric8 - fabric8-maven-plugin - 3.2.28 - - none - -service - - - - + + org.infinispan + infinispan-client-hotrod + - - - cart-tests - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - true - - - - - - - - - discount-tests - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - true - - - - - - - - + + + org.springframework.boot + spring-boot-starter-test + test + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + io.fabric8 + fabric8-maven-plugin + 3.2.28 + + none + -service + + + + + + + + cart-tests + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + true + + + + + + + + + discount-tests + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + true + + + + + + + + diff --git a/cart-spring-boot/src/main/java/com/redhat/coolstore/model/ShoppingCart.java b/cart-spring-boot/src/main/java/com/redhat/coolstore/model/ShoppingCart.java index efab8e8..9cce41b 100644 --- a/cart-spring-boot/src/main/java/com/redhat/coolstore/model/ShoppingCart.java +++ b/cart-spring-boot/src/main/java/com/redhat/coolstore/model/ShoppingCart.java @@ -6,108 +6,120 @@ public class ShoppingCart implements Serializable { - private static final long serialVersionUID = -1108043957592113528L; - - private double cartItemTotal; - - private double cartItemPromoSavings; - - private double shippingTotal; - - private double shippingPromoSavings; - - private double cartTotal; - - private List shoppingCartItemList = new ArrayList(); - - public ShoppingCart() { - - } - - public List getShoppingCartItemList() { - return shoppingCartItemList; - } - - public void setShoppingCartItemList(List shoppingCartItemList) { - this.shoppingCartItemList = shoppingCartItemList; - } - - public void resetShoppingCartItemList() { - shoppingCartItemList = new ArrayList(); - } - - public void addShoppingCartItem(ShoppingCartItem sci) { - - if ( sci != null ) { - - shoppingCartItemList.add(sci); - - } - - } - - public boolean removeShoppingCartItem(ShoppingCartItem sci) { - - boolean removed = false; - - if ( sci != null ) { - - removed = shoppingCartItemList.remove(sci); - - } - - return removed; - - } - - public double getCartItemTotal() { - return cartItemTotal; - } - - public void setCartItemTotal(double cartItemTotal) { - this.cartItemTotal = cartItemTotal; - } - - public double getShippingTotal() { - return shippingTotal; - } - - public void setShippingTotal(double shippingTotal) { - this.shippingTotal = shippingTotal; - } - - public double getCartTotal() { - return cartTotal; - } - - public void setCartTotal(double cartTotal) { - this.cartTotal = cartTotal; - } - - public double getCartItemPromoSavings() { - return cartItemPromoSavings; - } - - public void setCartItemPromoSavings(double cartItemPromoSavings) { - this.cartItemPromoSavings = cartItemPromoSavings; - } - - public double getShippingPromoSavings() { - return shippingPromoSavings; - } - - public void setShippingPromoSavings(double shippingPromoSavings) { - this.shippingPromoSavings = shippingPromoSavings; - } - - @Override - public String toString() { - return "ShoppingCart [cartItemTotal=" + cartItemTotal - + ", cartItemPromoSavings=" + cartItemPromoSavings - + ", shippingTotal=" + shippingTotal - + ", shippingPromoSavings=" + shippingPromoSavings - + ", cartTotal=" + cartTotal + ", shoppingCartItemList=" - + shoppingCartItemList + "]"; - } - + private static final long serialVersionUID = -1108043957592113528L; + + private double cartItemTotal; + + private double cartItemPromoSavings; + + private double shippingTotal; + + private double shippingPromoSavings; + + private double cartTotal; + + private String cartId; + + private List shoppingCartItemList = new ArrayList(); + + public ShoppingCart(String cartId) { + this.cartId = cartId; + } + + public String getCartId() { + return cartId; + } + + public void setCartId(String cartId) { + this.cartId = cartId; + } + + + public List getShoppingCartItemList() { + return shoppingCartItemList; + } + + public void setShoppingCartItemList(List shoppingCartItemList) { + this.shoppingCartItemList = shoppingCartItemList; + } + + public void resetShoppingCartItemList() { + shoppingCartItemList = new ArrayList(); + } + + public void addShoppingCartItem(ShoppingCartItem sci) { + + if (sci != null) { + + shoppingCartItemList.add(sci); + + } + + } + + public boolean removeShoppingCartItem(ShoppingCartItem sci) { + + boolean removed = false; + + if (sci != null) { + + removed = shoppingCartItemList.remove(sci); + + } + + return removed; + + } + + public double getCartItemTotal() { + return cartItemTotal; + } + + public void setCartItemTotal(double cartItemTotal) { + this.cartItemTotal = cartItemTotal; + } + + public double getShippingTotal() { + return shippingTotal; + } + + public void setShippingTotal(double shippingTotal) { + this.shippingTotal = shippingTotal; + } + + public double getCartTotal() { + return cartTotal; + } + + public void setCartTotal(double cartTotal) { + this.cartTotal = cartTotal; + } + + public double getCartItemPromoSavings() { + return cartItemPromoSavings; + } + + public void setCartItemPromoSavings(double cartItemPromoSavings) { + this.cartItemPromoSavings = cartItemPromoSavings; + } + + public double getShippingPromoSavings() { + return shippingPromoSavings; + } + + public void setShippingPromoSavings(double shippingPromoSavings) { + this.shippingPromoSavings = shippingPromoSavings; + } + + @Override + public String toString() { + return "ShoppingCart [cartId=" + cartId + + ", cartItemTotal=" + cartItemTotal + + ", cartItemPromoSavings=" + cartItemPromoSavings + + ", shippingTotal=" + shippingTotal + + ", shippingPromoSavings=" + shippingPromoSavings + + ", cartTotal=" + cartTotal + ", shoppingCartItemList=" + + shoppingCartItemList + "]"; + } + } diff --git a/cart-spring-boot/src/main/java/com/redhat/coolstore/rest/CartEndpoint.java b/cart-spring-boot/src/main/java/com/redhat/coolstore/rest/CartEndpoint.java index 7582256..d7c0004 100644 --- a/cart-spring-boot/src/main/java/com/redhat/coolstore/rest/CartEndpoint.java +++ b/cart-spring-boot/src/main/java/com/redhat/coolstore/rest/CartEndpoint.java @@ -31,7 +31,7 @@ @Scope(scopeName = WebApplicationContext.SCOPE_SESSION) @Path("/cart") public class CartEndpoint implements Serializable { - private static final Logger LOG = LoggerFactory.getLogger(CartEndpoint.class); + private static final Logger LOG = LoggerFactory.getLogger(CartEndpoint.class); /** * @@ -45,7 +45,6 @@ public class CartEndpoint implements Serializable { @Path("/{cartId}") @Produces(MediaType.APPLICATION_JSON) public ShoppingCart getCart(@PathParam("cartId") String cartId) { - return shoppingCartService.getShoppingCart(cartId); } @@ -55,30 +54,7 @@ public ShoppingCart getCart(@PathParam("cartId") String cartId) { public ShoppingCart add(@PathParam("cartId") String cartId, @PathParam("itemId") String itemId, @PathParam("quantity") int quantity) throws Exception { - ShoppingCart cart = shoppingCartService.getShoppingCart(cartId); - - Product product = shoppingCartService.getProduct(itemId); - - if (product == null) { - LOG.warn("Invalid product {} request to get added to the shopping cart. No product added", itemId); - return cart; - } - - ShoppingCartItem sci = new ShoppingCartItem(); - sci.setProduct(product); - sci.setQuantity(quantity); - sci.setPrice(product.getPrice()); - cart.addShoppingCartItem(sci); - - try { - shoppingCartService.priceShoppingCart(cart); - cart.setShoppingCartItemList(dedupeCartItems(cart.getShoppingCartItemList())); - } catch (Exception ex) { - cart.removeShoppingCartItem(sci); - throw ex; - } - - return cart; + return shoppingCartService.addItem(cartId, itemId, quantity); } @POST @@ -87,22 +63,7 @@ public ShoppingCart add(@PathParam("cartId") String cartId, public ShoppingCart set(@PathParam("cartId") String cartId, @PathParam("tmpId") String tmpId) throws Exception { - ShoppingCart cart = shoppingCartService.getShoppingCart(cartId); - ShoppingCart tmpCart = shoppingCartService.getShoppingCart(tmpId); - - if (tmpCart != null) { - cart.resetShoppingCartItemList(); - cart.setShoppingCartItemList(tmpCart.getShoppingCartItemList()); - } - - try { - shoppingCartService.priceShoppingCart(cart); - cart.setShoppingCartItemList(dedupeCartItems(cart.getShoppingCartItemList())); - } catch (Exception ex) { - throw ex; - } - - return cart; + return shoppingCartService.set(cartId, tmpId); } @DELETE @@ -112,24 +73,7 @@ public ShoppingCart delete(@PathParam("cartId") String cartId, @PathParam("itemId") String itemId, @PathParam("quantity") int quantity) throws Exception { - List toRemoveList = new ArrayList<>(); - - ShoppingCart cart = shoppingCartService.getShoppingCart(cartId); - - cart.getShoppingCartItemList().stream() - .filter(sci -> sci.getProduct().getItemId().equals(itemId)) - .forEach(sci -> { - if (quantity >= sci.getQuantity()) { - toRemoveList.add(sci); - } else { - sci.setQuantity(sci.getQuantity() - quantity); - } - }); - - toRemoveList.forEach(cart::removeShoppingCartItem); - - shoppingCartService.priceShoppingCart(cart); - return cart; + return shoppingCartService.deleteItem(cartId, itemId, quantity); } @POST @@ -137,31 +81,6 @@ public ShoppingCart delete(@PathParam("cartId") String cartId, @Produces(MediaType.APPLICATION_JSON) public ShoppingCart checkout(@PathParam("cartId") String cartId) { // TODO: register purchase of shoppingCart items by specific user in session - ShoppingCart cart = shoppingCartService.getShoppingCart(cartId); - cart.resetShoppingCartItemList(); - shoppingCartService.priceShoppingCart(cart); - return cart; - } - - private List dedupeCartItems(List cartItems) { - List result = new ArrayList<>(); - Map quantityMap = new HashMap<>(); - for (ShoppingCartItem sci : cartItems) { - if (quantityMap.containsKey(sci.getProduct().getItemId())) { - quantityMap.put(sci.getProduct().getItemId(), quantityMap.get(sci.getProduct().getItemId()) + sci.getQuantity()); - } else { - quantityMap.put(sci.getProduct().getItemId(), sci.getQuantity()); - } - } - - for (String itemId : quantityMap.keySet()) { - Product p = shoppingCartService.getProduct(itemId); - ShoppingCartItem newItem = new ShoppingCartItem(); - newItem.setQuantity(quantityMap.get(itemId)); - newItem.setPrice(p.getPrice()); - newItem.setProduct(p); - result.add(newItem); - } - return result; + return shoppingCartService.checkout(cartId); } } diff --git a/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartService.java b/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartService.java index 76d6790..da736cc 100644 --- a/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartService.java +++ b/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartService.java @@ -4,7 +4,15 @@ import com.redhat.coolstore.model.ShoppingCart; public interface ShoppingCartService { - public void priceShoppingCart(ShoppingCart sc); - public ShoppingCart getShoppingCart(String cartId); - public Product getProduct(String itemId); + public ShoppingCart getShoppingCart(String cartId); + + public Product getProduct(String itemId); + + public ShoppingCart deleteItem(String cartId, String itemId, int quantity); + + public ShoppingCart checkout(String cartId); + + public ShoppingCart addItem(String cartId, String itemId, int quantity); + + public ShoppingCart set(String cartId, String tmpId); } diff --git a/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartServiceImpl.java b/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartServiceImpl.java index d02937b..12ba434 100644 --- a/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartServiceImpl.java +++ b/cart-spring-boot/src/main/java/com/redhat/coolstore/service/ShoppingCartServiceImpl.java @@ -1,5 +1,6 @@ package com.redhat.coolstore.service; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -8,6 +9,11 @@ import javax.annotation.PostConstruct; +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; +import org.infinispan.commons.api.BasicCacheContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -18,97 +24,221 @@ @Component public class ShoppingCartServiceImpl implements ShoppingCartService { - - @Autowired - ShippingService ss; - - @Autowired - CatalogService catalogServie; - - @Autowired - PromoService ps; - - @Value("${application.mode}") - String mode; - - private Map cartDB = new HashMap<>(); - - private Map productMap = new HashMap<>(); - - @PostConstruct - public void init(){ - if ("dev".contentEquals(mode)) { - // cache dummy product - Product dummy = new Product(); - dummy.setItemId("666"); - dummy.setName("Dummy Product"); - dummy.setPrice(50); - dummy.setDesc("Dummy product for testing in DEV mode"); - productMap.put(dummy.getItemId(), dummy); - } - } - - @Override - public ShoppingCart getShoppingCart(String cartId) { - if (!cartDB.containsKey(cartId)) { - ShoppingCart c = new ShoppingCart(); - cartDB.put(cartId, c); - return c; - } else { - return cartDB.get(cartId); - } - } - - @Override - public void priceShoppingCart(ShoppingCart sc) { - if ( sc != null ) { - initShoppingCartForPricing(sc); - - if ( sc.getShoppingCartItemList() != null && sc.getShoppingCartItemList().size() > 0) { - ps.applyCartItemPromotions(sc); - - for (ShoppingCartItem sci : sc.getShoppingCartItemList()) { - sc.setCartItemPromoSavings(sc.getCartItemPromoSavings() + sci.getPromoSavings() * sci.getQuantity()); - sc.setCartItemTotal(sc.getCartItemTotal() + sci.getPrice() * sci.getQuantity()); - } - - ss.calculateShipping(sc); - } - - ps.applyShippingPromotions(sc); - - sc.setCartTotal(sc.getCartItemTotal() + sc.getShippingTotal()); - } - } - - private void initShoppingCartForPricing(ShoppingCart sc) { - sc.setCartItemTotal(0); - sc.setCartItemPromoSavings(0); - sc.setShippingTotal(0); - sc.setShippingPromoSavings(0); - sc.setCartTotal(0); - - for (ShoppingCartItem sci : sc.getShoppingCartItemList()) { - Product p = getProduct(sci.getProduct().getItemId()); - - //if product exist, create new product to reset price - if ( p != null ) { - sci.setProduct(new Product(p.getItemId(), p.getName(), p.getDesc(), p.getPrice())); - sci.setPrice(p.getPrice()); - } - - sci.setPromoSavings(0); - } - } - - @Override - public Product getProduct(String itemId) { - if (!productMap.containsKey(itemId)) { - // Fetch and cache products. TODO: Cache should expire at some point! - List products = catalogServie.products(); - productMap = products.stream().collect(Collectors.toMap(Product::getItemId, Function.identity())); - } - - return productMap.get(itemId); - } + + private static final Logger LOG = LoggerFactory.getLogger(ShoppingCartServiceImpl.class); + + @Autowired + ShippingService ss; + + @Autowired + CatalogService catalogServie; + + @Autowired + PromoService ps; + + @Value("${application.mode}") + String mode; + + private Map carts; + + private Map productMap = new HashMap<>(); + + @PostConstruct + public void init() { + if ("dev".contentEquals(mode)) { + // cache dummy product + Product dummy = new Product(); + dummy.setItemId("666"); + dummy.setName("Dummy Product"); + dummy.setPrice(50); + dummy.setDesc("Dummy product for testing in DEV mode"); + productMap.put(dummy.getItemId(), dummy); + } + + String host = System.getenv("DATAGRID_HOST"); + String port = System.getenv("DATAGRID_PORT"); + + if (host != null) { + ConfigurationBuilder builder = new ConfigurationBuilder(); + builder.addServer() + .host(host) + .port(Integer.parseInt(port)); + BasicCacheContainer manager = new RemoteCacheManager(builder.build()); + carts = manager.getCache("cart"); + + LOG.info("Using remote JBoss Data Grid (Hot Rod) on {}:{} for cart data", host, port); + } else { + carts = new HashMap<>(); + LOG.info("Using local cache for cart data"); + } + } + + @Override + public ShoppingCart getShoppingCart(String cartId) { + if (!carts.containsKey(cartId)) { + ShoppingCart cart = new ShoppingCart(cartId); + carts.put(cartId, cart); + return cart; + } + + return carts.get(cartId); + } + + private void priceShoppingCart(ShoppingCart sc) { + if (sc != null) { + initShoppingCartForPricing(sc); + + if (sc.getShoppingCartItemList() != null && sc.getShoppingCartItemList().size() > 0) { + ps.applyCartItemPromotions(sc); + + for (ShoppingCartItem sci : sc.getShoppingCartItemList()) { + sc.setCartItemPromoSavings(sc.getCartItemPromoSavings() + sci.getPromoSavings() * sci.getQuantity()); + sc.setCartItemTotal(sc.getCartItemTotal() + sci.getPrice() * sci.getQuantity()); + } + + ss.calculateShipping(sc); + } + + ps.applyShippingPromotions(sc); + + sc.setCartTotal(sc.getCartItemTotal() + sc.getShippingTotal()); + } + } + + private void initShoppingCartForPricing(ShoppingCart sc) { + sc.setCartItemTotal(0); + sc.setCartItemPromoSavings(0); + sc.setShippingTotal(0); + sc.setShippingPromoSavings(0); + sc.setCartTotal(0); + + for (ShoppingCartItem sci : sc.getShoppingCartItemList()) { + Product p = getProduct(sci.getProduct().getItemId()); + + //if product exist, create new product to reset price + if (p != null) { + sci.setProduct(new Product(p.getItemId(), p.getName(), p.getDesc(), p.getPrice())); + sci.setPrice(p.getPrice()); + } + + sci.setPromoSavings(0); + } + } + + @Override + public Product getProduct(String itemId) { + if (!productMap.containsKey(itemId)) { + // Fetch and cache products. TODO: Cache should expire at some point! + List products = catalogServie.products(); + productMap = products.stream().collect(Collectors.toMap(Product::getItemId, Function.identity())); + } + + return productMap.get(itemId); + } + + @Override + public ShoppingCart deleteItem(String cartId, String itemId, int quantity) { + List toRemoveList = new ArrayList<>(); + + ShoppingCart cart = getShoppingCart(cartId); + + cart.getShoppingCartItemList().stream() + .filter(sci -> sci.getProduct().getItemId().equals(itemId)) + .forEach(sci -> { + if (quantity >= sci.getQuantity()) { + toRemoveList.add(sci); + } else { + sci.setQuantity(sci.getQuantity() - quantity); + } + }); + + toRemoveList.forEach(cart::removeShoppingCartItem); + priceShoppingCart(cart); + carts.put(cartId, cart); + + return cart; + } + + @Override + public ShoppingCart checkout(String cartId) { + ShoppingCart cart = getShoppingCart(cartId); + cart.resetShoppingCartItemList(); + priceShoppingCart(cart); + carts.put(cartId, cart); + return cart; + } + + @Override + public ShoppingCart addItem(String cartId, String itemId, int quantity) { + ShoppingCart cart = getShoppingCart(cartId); + LOG.info("### Got shopping cart: {}", cart); + Product product = getProduct(itemId); + + if (product == null) { + LOG.warn("Invalid product {} request to get added to the shopping cart. No product added", itemId); + return cart; + } + + ShoppingCartItem sci = new ShoppingCartItem(); + sci.setProduct(product); + sci.setQuantity(quantity); + sci.setPrice(product.getPrice()); + cart.addShoppingCartItem(sci); + + try { + priceShoppingCart(cart); + cart.setShoppingCartItemList(dedupeCartItems(cart)); + } catch (Exception ex) { + cart.removeShoppingCartItem(sci); + throw ex; + } + + carts.put(cartId, cart); + return cart; + } + + @Override + public ShoppingCart set(String cartId, String tmpId) { + + ShoppingCart cart = getShoppingCart(cartId); + ShoppingCart tmpCart = getShoppingCart(tmpId); + + if (tmpCart != null) { + cart.resetShoppingCartItemList(); + cart.setShoppingCartItemList(tmpCart.getShoppingCartItemList()); + } + + try { + priceShoppingCart(cart); + cart.setShoppingCartItemList(dedupeCartItems(cart)); + } catch (Exception ex) { + throw ex; + } + + carts.put(cartId, cart); + return cart; + } + + private List dedupeCartItems(ShoppingCart sc) { + List result = new ArrayList<>(); + Map quantityMap = new HashMap<>(); + for (ShoppingCartItem sci : sc.getShoppingCartItemList()) { + if (quantityMap.containsKey(sci.getProduct().getItemId())) { + quantityMap.put(sci.getProduct().getItemId(), quantityMap.get(sci.getProduct().getItemId()) + sci.getQuantity()); + } else { + quantityMap.put(sci.getProduct().getItemId(), sci.getQuantity()); + } + } + + for (String itemId : quantityMap.keySet()) { + Product p = getProduct(itemId); + ShoppingCartItem newItem = new ShoppingCartItem(); + newItem.setQuantity(quantityMap.get(itemId)); + newItem.setPrice(p.getPrice()); + newItem.setProduct(p); + result.add(newItem); + } + + return result; + } } \ No newline at end of file