// Path: demo-service-interface/src/main/java/app/demo/api/ProductWebService.java
// public interface ProductWebService {
//     @GET
//     @Path("/product")
//     SearchProductResponse search(SearchProductRequest request);
// 
//     @GET
//     @Path("/product/:id")
//     Optional<ProductView> get(@PathParam("id") String id);
// 
//     @POST
//     @Path("/product")
//     @ResponseStatus(HTTPStatus.CREATED)
//     void create(CreateProductRequest request);
// 
//     @PATCH
//     @Path("/product/:id")
//     void update(@PathParam("id") String id, UpdateProductRequest request);
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/CreateProductRequest.java
// public class CreateProductRequest {
//     @NotNull(message = "id is required")
//     @Property(name = "id")
//     public String id;
// 
//     @NotNull(message = "name is required")
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/ProductView.java
// public class ProductView {
//     @Property(name = "id")
//     public String id;
// 
//     @NotNull(message = "name is required")
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// 
//     @Property(name = "created_time")
//     public LocalDateTime createdTime;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/SearchProductRequest.java
// public class SearchProductRequest {
//     @NotNull(message = "name is required")
//     @QueryParam(name = "name")
//     public String name;
// 
//     @QueryParam(name = "desc")
//     public String description;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/SearchProductResponse.java
// public class SearchProductResponse {
//     @Property(name = "products")
//     public List<ProductView> products;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/UpdateProductRequest.java
// public class UpdateProductRequest {
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// }
// 
// Path: demo-service/src/main/java/app/demo/product/service/ProductService.java
// public class ProductService {
//     private final Map<String, ProductView> products = Maps.newConcurrentHashMap();
//     @Inject
//     Cache<ProductView> cache;
// 
//     public Optional<ProductView> get(String id) {
//         ProductView view = cache.get(id, products::get);
//         return Optional.ofNullable(view);
//     }
// 
//     public void create(CreateProductRequest request) {
//         ProductView product = new ProductView();
//         product.id = request.id;
//         product.name = request.name;
//         product.description = request.description;
//         product.createdTime = LocalDateTime.now();
//         products.put(product.id, product);
//     }
// 
//     public void update(String id, UpdateProductRequest request) {
//         ProductView product = products.get(id);
//         if (product == null) throw new NotFoundException("product not found");
//         if (request.name != null) product.name = request.name;
//     }
// }


import app.demo.api.ProductWebService;
import app.demo.api.product.CreateProductRequest;
import app.demo.api.product.ProductView;
import app.demo.api.product.SearchProductRequest;
import app.demo.api.product.SearchProductResponse;
import app.demo.api.product.UpdateProductRequest;
import app.demo.product.service.ProductService;
import core.framework.inject.Inject;
import core.framework.log.ActionLogContext;
import core.framework.util.Lists;
import core.framework.web.rate.LimitRate;
import java.util.Optional;
package app.demo.product.web;



/**
 * @author neo
 */
public class ProductWebServiceImpl implements ProductWebService {
    @Inject
    ProductService productService;

    @Override
    public SearchProductResponse search(SearchProductRequest request) {
        SearchProductResponse response = new SearchProductResponse();
        response.products = Lists.newArrayList();
        return response;
    }

    @LimitRate("product")
    @Override
    public Optional<ProductView> get(String id) {
        ActionLogContext.put("pid", id);
        return productService.get(id);
    }

    @Override
    public void create(CreateProductRequest request) {
        productService.create(request);
    }

    @Override
// Path: demo-service-interface/src/main/java/app/demo/api/ProductWebService.java
// public interface ProductWebService {
//     @GET
//     @Path("/product")
//     SearchProductResponse search(SearchProductRequest request);
// 
//     @GET
//     @Path("/product/:id")
//     Optional<ProductView> get(@PathParam("id") String id);
// 
//     @POST
//     @Path("/product")
//     @ResponseStatus(HTTPStatus.CREATED)
//     void create(CreateProductRequest request);
// 
//     @PATCH
//     @Path("/product/:id")
//     void update(@PathParam("id") String id, UpdateProductRequest request);
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/CreateProductRequest.java
// public class CreateProductRequest {
//     @NotNull(message = "id is required")
//     @Property(name = "id")
//     public String id;
// 
//     @NotNull(message = "name is required")
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/ProductView.java
// public class ProductView {
//     @Property(name = "id")
//     public String id;
// 
//     @NotNull(message = "name is required")
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// 
//     @Property(name = "created_time")
//     public LocalDateTime createdTime;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/SearchProductRequest.java
// public class SearchProductRequest {
//     @NotNull(message = "name is required")
//     @QueryParam(name = "name")
//     public String name;
// 
//     @QueryParam(name = "desc")
//     public String description;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/SearchProductResponse.java
// public class SearchProductResponse {
//     @Property(name = "products")
//     public List<ProductView> products;
// }
// 
// Path: demo-service-interface/src/main/java/app/demo/api/product/UpdateProductRequest.java
// public class UpdateProductRequest {
//     @Property(name = "name")
//     public String name;
// 
//     @Property(name = "desc")
//     public String description;
// }
// 
// Path: demo-service/src/main/java/app/demo/product/service/ProductService.java
// public class ProductService {
//     private final Map<String, ProductView> products = Maps.newConcurrentHashMap();
//     @Inject
//     Cache<ProductView> cache;
// 
//     public Optional<ProductView> get(String id) {
//         ProductView view = cache.get(id, products::get);
//         return Optional.ofNullable(view);
//     }
// 
//     public void create(CreateProductRequest request) {
//         ProductView product = new ProductView();
//         product.id = request.id;
//         product.name = request.name;
//         product.description = request.description;
//         product.createdTime = LocalDateTime.now();
//         products.put(product.id, product);
//     }
// 
//     public void update(String id, UpdateProductRequest request) {
//         ProductView product = products.get(id);
//         if (product == null) throw new NotFoundException("product not found");
//         if (request.name != null) product.name = request.name;
//     }
// }


// Path: demo-service/src/main/java/app/demo/product/web/ProductWebServiceImpl.java
import app.demo.api.ProductWebService;
import app.demo.api.product.CreateProductRequest;
import app.demo.api.product.ProductView;
import app.demo.api.product.SearchProductRequest;
import app.demo.api.product.SearchProductResponse;
import app.demo.api.product.UpdateProductRequest;
import app.demo.product.service.ProductService;
import core.framework.inject.Inject;
import core.framework.log.ActionLogContext;
import core.framework.util.Lists;
import core.framework.web.rate.LimitRate;
import java.util.Optional;

package app.demo.product.web;



/**
 * @author neo
 */
public class ProductWebServiceImpl implements ProductWebService {
    @Inject
    ProductService productService;

    @Override
    public SearchProductResponse search(SearchProductRequest request) {
        SearchProductResponse response = new SearchProductResponse();
        response.products = Lists.newArrayList();
        return response;
    }

    @LimitRate("product")
    @Override
    public Optional<ProductView> get(String id) {
        ActionLogContext.put("pid", id);
        return productService.get(id);
    }

    @Override
    public void create(CreateProductRequest request) {
        productService.create(request);
    }

    @Override
    public void update(String id, UpdateProductRequest request) {