This is an automated email from the ASF dual-hosted git repository. mabin pushed a commit to branch houserush-sample in repository https://gitbox.apache.org/repos/asf/servicecomb-samples.git
commit 0fddf7db2ceb438e6abb45d49b528dad5959b8fb Author: alec.zheng <[email protected]> AuthorDate: Fri Aug 2 11:18:53 2019 +0800 first commit for house-order microservice --- houserush/house-order/README.md | 95 ++++++++++++++ .../houserush/sale/HouseOrderApplication.java | 43 +++++++ .../practise/houserush/sale/HouseOrderConfig.java | 26 ++++ .../houserush/sale/aggregate/HouseOrder.java | 59 +++++++++ .../practise/houserush/sale/aggregate/Sale.java | 71 +++++++++++ .../practise/houserush/sale/api/HouseOrderApi.java | 39 ++++++ .../houserush/sale/api/HouseOrderApiRestImpl.java | 75 +++++++++++ .../practise/houserush/sale/dao/HouseOrderDao.java | 38 ++++++ .../practise/houserush/sale/dao/SaleDao.java | 24 ++++ .../houserush/sale/rpc/CustomerManageApi.java | 26 ++++ .../practise/houserush/sale/rpc/RealestateApi.java | 29 +++++ .../practise/houserush/sale/rpc/po/Customer.java | 31 +++++ .../practise/houserush/sale/rpc/po/House.java | 27 ++++ .../houserush/sale/rpc/po/Qualification.java | 27 ++++ .../practise/houserush/sale/rpc/po/Realestate.java | 27 ++++ .../houserush/sale/service/HouseOrderService.java | 39 ++++++ .../sale/service/HouseOrderServiceImpl.java | 142 +++++++++++++++++++++ .../src/main/resources/microservice.yaml | 48 +++++++ 18 files changed, 866 insertions(+) diff --git a/houserush/house-order/README.md b/houserush/house-order/README.md new file mode 100644 index 0000000..1ed80b0 --- /dev/null +++ b/houserush/house-order/README.md @@ -0,0 +1,95 @@ +## 微服务 House-Order + +### 主要职责 +该微服务主要有4个职责 +1. 管理员用作开售活动的管理。 +2. 普通用户"**抢购**"房产。 +3. 管理员获取抢购活动的结果。 +4. 普通用户查询自己的抢购结果。 + +### 主要设计考量 +1. 简单,抢购的核心接口只有1,2个,因为这部分后续需要优化性能,所以越简单,后续优化越容易。 +2. 第一版利用同步调用的方式,尽量不引入冗余数据,减少数据一致性的考量。 + +### 后续改进的关注点 TODO list: +1. 需要减少对其他微服务的同步调用,考虑引入异步的事务消息更新机制。提高抢购的性能。 +2. 可能会引入缓存系统,初步定为redis。 +3. 需要跨微服务事务机制,保证数据库的一致性。 + +### 数据表设计 + +主要有2张表: +1. house_orders表,这张表既表示了待抢房源,也表示了抢购订单(抢购结果),差别在与customer_id列是否为null和state列的值。 +在开始抢购之前,customer_id为空,state为new, 记录这次开售活动有哪些房源参与销售。开售中和开售后记录抢购结果。 +即谁抢购到了该房产。 +2. sales表,表示开售活动,主要记录了开售活动的起止时间。sale has_many house_orders。表示这次开售 +活动有哪些房产可售。 + +sales表: + +| column name | type | brief | description | +| -------------- | ------------ | ------- | -------------- | +| id | int | 主键 | | +| state | varchar(20) | 订单状态 | new->published-> ongoing -> finished | +| begin_at | timestamp | 开售活动开始时间 | | +| end_at | timestamp | 开售活动结束时间 | | +| realestate_id | int | 楼盘id | 一次开售活动只能针对同属一个楼盘的部分房源 | +| deleted_at | timestamp | 开售活动删除时间 | 一次开售活动只有在未发布前可以进行删除或编辑,软删除方案 | + + +house_orders表: + +| column name | type | 简介 | 更多说明 | +| -------------- | ------------ | ------- | -------------- | +| id | int | 主键 | | +| sale_id | int | 外键:开售活动id | | +| customer_id | int | 客户id | 记录了谁抢到了该房源,开售前为空 | +| state | varchar(20) | 订单状态 | new 是待抢,confirmed是已抢 | +| ordered_at | timestamp | 抢购时间 | state变为confirmed的时间 | + +### 接口设计 + + +##### 管理开售活动相关 +```java + @PostMapping("sales") + Sale createSale(@RequestBody Sale sale); + + @GetMapping("sales/{saleId}") + Sale findSale(@PathVariable int saleId); + //获取开售活动详情。 + + @PutMapping("sales/{saleId}") + Sale Sale updateSale(@PathVariable int saleId, @RequestBody Sale sale); + //开售活动发布是通过该接口,一旦发布,不能再修改了,也不能删除。 + + @DeleteMapping("sales/{saleId}") + void removeSale(@PathVariable int saleId); + + @GetMapping("sales") + List<Sale> indexSales(); + //对客户列出客户有抢购资格的还未开始的开售活动,已开始时间排序;对管理员,列出所有的开售活动。 + + @PostMapping("sales/{saleId}/house_orders") + createHouseOrders(@PathVariable int saleId, @RequestBody List<Integer> houseIds); + //为开售活动创建房源,创建时需要检查这些房源是否已被其他开售活动锁定或售出。 + //需要先对这些房源加锁后再添加到当前开售活动中,要注意事务的应用。 + +``` + +##### 执行抢购相关 +```java + @PutMapping("house_orders/{houseOrderId}") + HouseOrder placeHouseOrder(@RequestHeader int customerId, @PathVariable int houseOrderId) + //修改house_orders的customer_id列,抢购前需要检查该房源是否已被占用, + // select for update加锁,注意事务应用。 + // +``` + +### 依赖其他微服务。 +1. find 和 index Sale的时候,需要调用realestate微服务的相关接口获取 +Sale关联楼盘的详细信息。 +2. createHouseOrders接口需要依赖realestate微服务查询房源状态和加锁,见接口说明。 +3. 依赖CustomerManage微服务,查询当前抢购的客户是否还有抢购的资格。 + + diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderApplication.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderApplication.java new file mode 100644 index 0000000..63a6875 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderApplication.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale; + +import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory; +import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +@SpringBootApplication +@EnableServiceComb +@EnableJpaAuditing +public class HouseOrderApplication { + public static void main(String[] args) { + configBeforeBoot(); + SpringApplication.run(HouseOrderApplication.class, args); + } + + private static void configBeforeBoot() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + RestObjectMapperFactory.getRestObjectMapper().setDateFormat(simpleDateFormat); + } +} diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderConfig.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderConfig.java new file mode 100644 index 0000000..f681976 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/HouseOrderConfig.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableJpaRepositories(basePackages = "org.apache.servicecomb.samples.practise.houserush") +public class HouseOrderConfig { +} diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/HouseOrder.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/HouseOrder.java new file mode 100644 index 0000000..3b8b863 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/HouseOrder.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.aggregate; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.util.Date; + +@Data +@Entity +@Table(name = "house_orders") +@EntityListeners(AuditingEntityListener.class) +public class HouseOrder { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + @JsonIgnore + @ManyToOne + @JoinColumn(name = "sale_id") + private Sale sale; + + private Integer customerId; + + private String state = "new"; + + private Integer houseId; + + @Temporal(TemporalType.TIMESTAMP) + private Date orderedAt; + + @CreatedDate + @Temporal(TemporalType.TIMESTAMP) + private Date CreatedAt; + + @LastModifiedDate + @Temporal(TemporalType.TIMESTAMP) + private Date UpdatedAt; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/Sale.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/Sale.java new file mode 100644 index 0000000..a0ea966 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/aggregate/Sale.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.aggregate; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.Where; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Data +@Entity +@Table(name = "sales") +@SQLDelete(sql = "update sales set deleted_at = now() where id = ?") +@Where(clause = "deleted_at is null") +@EntityListeners(AuditingEntityListener.class) +public class Sale { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + private String state = "new"; + + @Temporal(TemporalType.TIMESTAMP) + private Date beginAt; + + @Temporal(TemporalType.TIMESTAMP) + private Date endAt; + + @JsonIgnore + @OneToMany(mappedBy = "sale") + private List<HouseOrder> houseOrders = new ArrayList<>(); + + private Integer realestateId; + + @Transient + private String realestateName; + + @Temporal(TemporalType.TIMESTAMP) + private Date deletedAt; + + @CreatedDate + @Temporal(TemporalType.TIMESTAMP) + private Date createdAt; + + @LastModifiedDate + @Temporal(TemporalType.TIMESTAMP) + private Date updatedAt; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApi.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApi.java new file mode 100644 index 0000000..13207d9 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApi.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.api; + +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.HouseOrder; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.Sale; + +import java.util.List; + +public interface HouseOrderApi { + List<HouseOrder> createHouseOrders(int saleId, List<Integer> houseIds); + + HouseOrder placeHouseOrder(int customerId, int houseOrderId); + + Sale createSale(Sale sale); + + Sale findSale(int saleId); + + Sale updateSale(int saleId, Sale sale); + + void removeSale(int saleId); + + List<Sale> indexSales(); +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApiRestImpl.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApiRestImpl.java new file mode 100644 index 0000000..2a74fc5 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/api/HouseOrderApiRestImpl.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.api; + +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.HouseOrder; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.Sale; +import org.apache.servicecomb.samples.practise.houserush.sale.service.HouseOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestSchema(schemaId = "houseOrderApiRest") +@RequestMapping("/") +public class HouseOrderApiRestImpl implements HouseOrderApi { + @Autowired + HouseOrderService houseOrderService; + + @PostMapping("sales/{saleId}/house_orders") + public List<HouseOrder> createHouseOrders(@PathVariable int saleId, @RequestBody List<Integer> houseIds) { + return houseOrderService.createHouseOrders(saleId, houseIds); + } + + @PutMapping("house_orders/{houseOrderId}") + public HouseOrder placeHouseOrder(@RequestHeader int customerId, @PathVariable int houseOrderId) { + return houseOrderService.placeHouseOrder(customerId, houseOrderId); + } + + @Override + @PostMapping("sales") + public Sale createSale(@RequestBody Sale sale) { + return houseOrderService.createSale(sale); + } + + @Override + @GetMapping("sales/{saleId}") + public Sale findSale(@PathVariable int saleId) { + return houseOrderService.findSale(saleId); + } + + @Override + @PutMapping("sales/{saleId}") + public Sale updateSale(@PathVariable int saleId, @RequestBody Sale sale) { + sale.setId(saleId); + return houseOrderService.updateSale(sale); + } + + @Override + @DeleteMapping("sales/{saleId}") + public void removeSale(@PathVariable int saleId) { + houseOrderService.removeSale(saleId); + } + + @Override + @GetMapping("sales") + public List<Sale> indexSales() { + return houseOrderService.indexSales(); + } +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/HouseOrderDao.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/HouseOrderDao.java new file mode 100644 index 0000000..3e4bc2f --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/HouseOrderDao.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.dao; + +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.HouseOrder; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; +import org.springframework.data.jpa.repository.Query; + +import javax.persistence.LockModeType; +import java.util.List; + +public interface HouseOrderDao extends JpaRepository<HouseOrder, Integer> { + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("SELECT ho FROM HouseOrder ho WHERE ho.sale.id = ?1 and ho.houseId in (?2)") + List<HouseOrder> findAllBySaleIdAndHouseIdInForUpdate(int saleId, List<Integer> ids); + + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("SELECT ho FROM HouseOrder ho WHERE ho.id = ?1") + HouseOrder findOneForUpdate(int id); + + int countByCustomerIdAndSaleId(int customerId, int saleId); +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/SaleDao.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/SaleDao.java new file mode 100644 index 0000000..99795ec --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/dao/SaleDao.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.dao; + +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.Sale; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SaleDao extends JpaRepository<Sale, Integer> { +} diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/CustomerManageApi.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/CustomerManageApi.java new file mode 100644 index 0000000..0b30523 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/CustomerManageApi.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc; + +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.Customer; + +public interface CustomerManageApi { + Customer findCustomer(int customerId); + + int getQualificationsCount(int customerId, int saleId); +} diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/RealestateApi.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/RealestateApi.java new file mode 100644 index 0000000..0ca5393 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/RealestateApi.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc; + +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.House; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.Realestate; + +import java.util.List; + +public interface RealestateApi { + Realestate findRealestate(int id); + + List<House> lockHousesForSale(List<Integer> ids); +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Customer.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Customer.java new file mode 100644 index 0000000..d458315 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Customer.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc.po; + +import lombok.Data; + +import java.util.List; + +@Data +public class Customer { + private int id; + + private String phone; + + private List<Qualification> qualifications; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/House.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/House.java new file mode 100644 index 0000000..c122ef4 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/House.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc.po; + +import lombok.Data; + +@Data +public class House { + private Integer id; + + private String name; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Qualification.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Qualification.java new file mode 100644 index 0000000..027ca72 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Qualification.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc.po; + +import lombok.Data; + +@Data +public class Qualification { + private int id; + + private Integer saleId; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Realestate.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Realestate.java new file mode 100644 index 0000000..d7d3324 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/rpc/po/Realestate.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.rpc.po; + +import lombok.Data; + +@Data +public class Realestate { + private int id; + + private String name; +} \ No newline at end of file diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderService.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderService.java new file mode 100644 index 0000000..3333de3 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderService.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.service; + +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.HouseOrder; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.Sale; + +import java.util.List; + +public interface HouseOrderService { + List<HouseOrder> createHouseOrders(int saleId, List<Integer> houseIds); + + HouseOrder placeHouseOrder(int customerId, int houseOrderId); + + Sale createSale(Sale sale); + + Sale findSale(int saleId); + + Sale updateSale(Sale sale); + + void removeSale(int saleId); + + List<Sale> indexSales(); +} diff --git a/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderServiceImpl.java b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderServiceImpl.java new file mode 100644 index 0000000..eeed043 --- /dev/null +++ b/houserush/house-order/src/main/java/org/apache/servicecomb/samples/practise/houserush/sale/service/HouseOrderServiceImpl.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.practise.houserush.sale.service; + +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.HouseOrder; +import org.apache.servicecomb.samples.practise.houserush.sale.aggregate.Sale; +import org.apache.servicecomb.samples.practise.houserush.sale.dao.HouseOrderDao; +import org.apache.servicecomb.samples.practise.houserush.sale.dao.SaleDao; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.CustomerManageApi; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.RealestateApi; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.Customer; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.House; +import org.apache.servicecomb.samples.practise.houserush.sale.rpc.po.Realestate; +import org.apache.servicecomb.swagger.invocation.exception.InvocationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class HouseOrderServiceImpl implements HouseOrderService { + @Autowired + HouseOrderDao houseOrderDao; + + @Autowired + SaleDao saleDao; + + @RpcReference(microserviceName = "realestate", schemaId = "realestateApiRest") + private RealestateApi realestateApi; + + @RpcReference(microserviceName = "customer-manage", schemaId = "customerManageApiRest") + private CustomerManageApi customerManageApi; + + @Override + @Transactional + public List<HouseOrder> createHouseOrders(int saleId, List<Integer> houseIds) { + Sale sale = saleDao.findOne(saleId); + if (null == sale) { + throw new DataRetrievalFailureException("cannot create house for the non-existed sale."); + } + + List<HouseOrder> houseOrders = houseOrderDao.findAllBySaleIdAndHouseIdInForUpdate(saleId, houseIds); + if (!houseOrders.isEmpty()) { + throw new InvocationException(400, "", "some house is already in this sale."); + } + + List<House> houses = realestateApi.lockHousesForSale(houseIds); + List<HouseOrder> resHouseOrders = new ArrayList<>(); + houses.forEach(house -> { + HouseOrder houseOrder = new HouseOrder(); + houseOrder.setHouseId(house.getId()); + houseOrder.setSale(sale); + houseOrderDao.save(houseOrder); + resHouseOrders.add(houseOrder); + + }); + return resHouseOrders; + } + + @Override + @Transactional + public HouseOrder placeHouseOrder(int customerId, int houseOrderId) { + HouseOrder houseOrder = houseOrderDao.findOneForUpdate(houseOrderId); + Sale sale = houseOrder.getSale(); + + if (null != houseOrder) { + if (null == houseOrder.getCustomerId()) { + Customer customer = customerManageApi.findCustomer(customerId); + int qualificationsCount = customerManageApi.getQualificationsCount(customerId, sale.getId()); + + int ordersCount = houseOrderDao.countByCustomerIdAndSaleId(customerId, sale.getId()); + + if (qualificationsCount <= ordersCount) { + throw new InvocationException(400, "", "do not have the enough qualification to buy houses in this sale, " + + "the qualifications count is " + qualificationsCount + " , the order count is " + ordersCount); + } + + houseOrder.setCustomerId(customerId); + houseOrder.setState("confirmed"); + houseOrderDao.save(houseOrder); + return houseOrder; + } else { + throw new InvocationException(400, "", "该住宅已被其他人选购,请选择其他房产。"); + } + } else { + throw new InvocationException(400, "", "选择的房产不在此次抢购活动中"); + } + } + + @Override + public Sale createSale(Sale sale) { + return saleDao.save(sale); + } + + @Override + public Sale findSale(int saleId) { + Sale sale = saleDao.findOne(saleId); + Realestate realestate = realestateApi.findRealestate(sale.getRealestateId()); + sale.setRealestateName(realestate.getName()); + return sale; + } + + @Override + @Transactional + public Sale updateSale(Sale sale) { + int id = sale.getId(); + if (saleDao.exists(id)) { + return saleDao.save(sale); + } else { + throw new DataRetrievalFailureException("cannot update the none-existed sale"); + } + } + + @Override + public void removeSale(int saleId) { + saleDao.delete(saleId); + } + + @Override + public List<Sale> indexSales() { + return saleDao.findAll(); + } +} diff --git a/houserush/house-order/src/main/resources/microservice.yaml b/houserush/house-order/src/main/resources/microservice.yaml new file mode 100644 index 0000000..5aa426a --- /dev/null +++ b/houserush/house-order/src/main/resources/microservice.yaml @@ -0,0 +1,48 @@ +# +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +# all interconnected microservices must belong to an application wth the same ID +APPLICATION_ID: houserush +service_description: + # name of the declaring microservice + name: house-order + version: 0.0.6 +servicecomb: + service: + registry: + address: http://127.0.0.1:30100 + instance: + watch: true + healthCheck: + interval: 5 + + rest: + address: 0.0.0.0:6788 + handler: + chain: + Provider: + default: bizkeeper-provider +spring: + datasource: + url: jdbc:mysql://127.0.0.1:3306/house_order?characterEncoding=utf8&useSSL=false + username: root + password: root + jpa: + properties: + hibernate: + enable_lazy_load_no_trans: true \ No newline at end of file
