// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/client/productcatalog/ProductCatalogClient.java
// public class ProductCatalogClient {
// 
//   private final Client client;
//   private final String serviceUrl;
// 
//   private ProductCatalogClient(Client client, String serviceUrl) {
//     this.client = client;
//     this.serviceUrl = serviceUrl;
//   }
// 
//   public static ProductCatalogClient create(Client client, String serviceUrl) {
//     return new ProductCatalogClient(client, serviceUrl);
//   }
// 
//   public ProductDto getProduct(String productId) {
//     return client.target(serviceUrl + productId).request().get(ProductDto.class);
//   }
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/domain/CartRepository.java
// public interface CartRepository {
// 
//   void save(Cart cart);
// 
//   Cart get(String cartId);
// 
//   Cart find(String cartId);
// 
//   void delete(String cartId);
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/infrastructure/InMemoryCartRepository.java
// public class InMemoryCartRepository implements CartRepository {
// 
//   private ConcurrentHashMap<String, Cart> sessions = new ConcurrentHashMap<>();
// 
//   public void save(Cart cart) {
//     if (sessions.putIfAbsent(cart.cartId, cart) != null) {
//       throw new IllegalArgumentException(format("Shopping cart with id '%s' already exists", cart.cartId));
//     }
//   }
// 
//   public Cart get(String cartId) {
//     Cart cart = sessions.get(cartId);
//     checkArgument(cart != null, "No shopping cart with id '%s' exists", cartId);
//     return cart;
//   }
// 
//   public Cart find(String cartId) {
//     return sessions.get(cartId);
//   }
// 
//   public void delete(String cartId) {
//     sessions.remove(cartId);
//   }
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/resource/CartResource.java
// @Path("carts")
// @Produces(APPLICATION_JSON)
// @Consumes(APPLICATION_JSON)
// public class CartResource {
// 
//   private final Logger logger = LoggerFactory.getLogger(getClass());
//   private final ProductCatalogClient productCatalogClient;
//   private final CartRepository cartRepository;
// 
//   public CartResource(ProductCatalogClient productCatalogClient, CartRepository cartRepository) {
//     this.productCatalogClient = productCatalogClient;
//     this.cartRepository = cartRepository;
//   }
// 
//   @POST
//   public void initCart(@Valid CreateCartRequest cart) {
//     cartRepository.save(new Cart(cart.cartId));
//   }
// 
//   @POST
//   @Path("{cartId}/items")
//   public CartDto addItem(@PathParam("cartId") String cartId, AddItemRequest addItemRequest) {
//     Cart cart = cartRepository.get(cartId);
//     logger.debug("Got addItem request " + addItemRequest);
//     ProductDto product = productCatalogClient.getProduct(addItemRequest.productId);
//     assertProductExists(addItemRequest.productId, product);
//     Item item = new Item(new ProductId(addItemRequest.productId), product.book.title, product.price);
//     logger.info("Adding item to cart: " + item);
//     cart.add(item);
//     return CartDtoFactory.fromCart(cart);
//   }
// 
//   @GET
//   @Path("{cartId}")
//   public Response getCart(@PathParam("cartId") String cartId) {
//     Cart cart = cartRepository.find(cartId);
//     if (cart == null) {
//       return status(NOT_FOUND).entity(format("Cart with id '%s' does not exist", cartId)).build();
//     } else {
//       logger.info("Returning cart with [{}] lines", cart.getLineCount());
//       return Response.ok().entity(CartDtoFactory.fromCart(cart)).build();
//     }
//   }
// 
//   @DELETE
//   @Path("{cartId}")
//   public void deleteCart(@PathParam("cartId") String cartId) {
//     cartRepository.delete(cartId);
//     logger.info("Shopping cart for session [{}] cleared", cartId);
//   }
// 
//   private void assertProductExists(String productId, ProductDto product) {
//     if (product == null) {
//       throw new WebApplicationException(status(BAD_REQUEST)
//           .entity("Product with id '" + productId + "' could not be found").build());
//     }
//   }
// 
// }


import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.client.JerseyClientBuilder;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.citerus.cqrs.bookstore.shopping.client.productcatalog.ProductCatalogClient;
import se.citerus.cqrs.bookstore.shopping.domain.CartRepository;
import se.citerus.cqrs.bookstore.shopping.infrastructure.InMemoryCartRepository;
import se.citerus.cqrs.bookstore.shopping.resource.CartResource;
import javax.ws.rs.client.Client;
package se.citerus.cqrs.bookstore.shopping.application;



public class ShoppingApplication extends Application<ShoppingConfiguration> {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  @Override
  public void initialize(Bootstrap<ShoppingConfiguration> bootstrap) {
    bootstrap.addBundle(new AssetsBundle("/assets/", "/", "index.html"));
  }

  @Override
  public void run(ShoppingConfiguration configuration, Environment environment) throws Exception {
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/client/productcatalog/ProductCatalogClient.java
// public class ProductCatalogClient {
// 
//   private final Client client;
//   private final String serviceUrl;
// 
//   private ProductCatalogClient(Client client, String serviceUrl) {
//     this.client = client;
//     this.serviceUrl = serviceUrl;
//   }
// 
//   public static ProductCatalogClient create(Client client, String serviceUrl) {
//     return new ProductCatalogClient(client, serviceUrl);
//   }
// 
//   public ProductDto getProduct(String productId) {
//     return client.target(serviceUrl + productId).request().get(ProductDto.class);
//   }
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/domain/CartRepository.java
// public interface CartRepository {
// 
//   void save(Cart cart);
// 
//   Cart get(String cartId);
// 
//   Cart find(String cartId);
// 
//   void delete(String cartId);
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/infrastructure/InMemoryCartRepository.java
// public class InMemoryCartRepository implements CartRepository {
// 
//   private ConcurrentHashMap<String, Cart> sessions = new ConcurrentHashMap<>();
// 
//   public void save(Cart cart) {
//     if (sessions.putIfAbsent(cart.cartId, cart) != null) {
//       throw new IllegalArgumentException(format("Shopping cart with id '%s' already exists", cart.cartId));
//     }
//   }
// 
//   public Cart get(String cartId) {
//     Cart cart = sessions.get(cartId);
//     checkArgument(cart != null, "No shopping cart with id '%s' exists", cartId);
//     return cart;
//   }
// 
//   public Cart find(String cartId) {
//     return sessions.get(cartId);
//   }
// 
//   public void delete(String cartId) {
//     sessions.remove(cartId);
//   }
// 
// }
// 
// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/resource/CartResource.java
// @Path("carts")
// @Produces(APPLICATION_JSON)
// @Consumes(APPLICATION_JSON)
// public class CartResource {
// 
//   private final Logger logger = LoggerFactory.getLogger(getClass());
//   private final ProductCatalogClient productCatalogClient;
//   private final CartRepository cartRepository;
// 
//   public CartResource(ProductCatalogClient productCatalogClient, CartRepository cartRepository) {
//     this.productCatalogClient = productCatalogClient;
//     this.cartRepository = cartRepository;
//   }
// 
//   @POST
//   public void initCart(@Valid CreateCartRequest cart) {
//     cartRepository.save(new Cart(cart.cartId));
//   }
// 
//   @POST
//   @Path("{cartId}/items")
//   public CartDto addItem(@PathParam("cartId") String cartId, AddItemRequest addItemRequest) {
//     Cart cart = cartRepository.get(cartId);
//     logger.debug("Got addItem request " + addItemRequest);
//     ProductDto product = productCatalogClient.getProduct(addItemRequest.productId);
//     assertProductExists(addItemRequest.productId, product);
//     Item item = new Item(new ProductId(addItemRequest.productId), product.book.title, product.price);
//     logger.info("Adding item to cart: " + item);
//     cart.add(item);
//     return CartDtoFactory.fromCart(cart);
//   }
// 
//   @GET
//   @Path("{cartId}")
//   public Response getCart(@PathParam("cartId") String cartId) {
//     Cart cart = cartRepository.find(cartId);
//     if (cart == null) {
//       return status(NOT_FOUND).entity(format("Cart with id '%s' does not exist", cartId)).build();
//     } else {
//       logger.info("Returning cart with [{}] lines", cart.getLineCount());
//       return Response.ok().entity(CartDtoFactory.fromCart(cart)).build();
//     }
//   }
// 
//   @DELETE
//   @Path("{cartId}")
//   public void deleteCart(@PathParam("cartId") String cartId) {
//     cartRepository.delete(cartId);
//     logger.info("Shopping cart for session [{}] cleared", cartId);
//   }
// 
//   private void assertProductExists(String productId, ProductDto product) {
//     if (product == null) {
//       throw new WebApplicationException(status(BAD_REQUEST)
//           .entity("Product with id '" + productId + "' could not be found").build());
//     }
//   }
// 
// }


// Path: shopping-context/src/main/java/se/citerus/cqrs/bookstore/shopping/application/ShoppingApplication.java
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.client.JerseyClientBuilder;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.citerus.cqrs.bookstore.shopping.client.productcatalog.ProductCatalogClient;
import se.citerus.cqrs.bookstore.shopping.domain.CartRepository;
import se.citerus.cqrs.bookstore.shopping.infrastructure.InMemoryCartRepository;
import se.citerus.cqrs.bookstore.shopping.resource.CartResource;
import javax.ws.rs.client.Client;

package se.citerus.cqrs.bookstore.shopping.application;



public class ShoppingApplication extends Application<ShoppingConfiguration> {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  @Override
  public void initialize(Bootstrap<ShoppingConfiguration> bootstrap) {
    bootstrap.addBundle(new AssetsBundle("/assets/", "/", "index.html"));
  }

  @Override
  public void run(ShoppingConfiguration configuration, Environment environment) throws Exception {
    CartRepository cartRepository = new InMemoryCartRepository();