Wow 微服务开发框架开源项目

我要开发同款
匿名用户2023年06月02日
62阅读
开发技术Kotlin
所属分类微服务框架、程序开发
授权协议Apache

作品详情

Wow是基于DDD、EventSourcing的现代响应式CQRS架构微服务开发框架。

领域驱动 | 事件驱动 | 测试驱动 | 声明式设计 | 响应式编程 | 命令查询职责分离 | 事件源

架构图

事件源

可观测性

SpringWebFlux集成自动注册 命令 路由处理函数(HandlerFunction),开发人员仅需编写领域模型,即可完成服务开发。

测试套件:80%+的测试覆盖率轻而易举Given->When->Expect.

前置条件理解 领域驱动设计:《实现领域驱动设计》、《领域驱动设计:软件核心复杂性应对之道》理解 命令查询职责分离(CQRS)理解 事件源架构理解 响应式编程特性 AggregateModeling SingleClass InheritancePattern AggregationPattern SagaModeling StatelessSaga TestSuite 兼容性测试规范(TCK) AggregateVerifier SagaVerifier EventSourcingEventStore MongoDB(Recommend) R2dbc DatabaseSharding TableSharding RedisSnapshot MongoDB R2dbc DatabaseSharding TableSharding ElasticSearch Redis(Recommend) CommandBus InMemoryCommandBus KafkaCommandBus (Recommend) RedisCommandBus LocalFirstCommandBus DomainEventBus InMemoryDomainEventBus KafkaDomainEventBus (Recommend) RedisDomainEventBus LocalFirstDomainEventBus StateEventBus InMemoryStateEventBus KafkaStateEventBus (Recommend) RedisStateEventBus LocalFirstStateEventBus Spring集成 SpringBootAutoConfiguration Automaticallyregister CommandAggregate to RouterFunction 可观测性 OpenTelemetry OpenApi WowMetadata Generator wow-compilerExampleExample

测试套件80%+的测试覆盖率轻而易举。

Given->When->Expect.

internalclassOrderTest{companionobject{valSHIPPING_ADDRESS=ShippingAddress("China","ShangHai","ShangHai","HuangPu","001")}privatefunmockCreateOrder():VerifiedStage<OrderState>{valtenantId=GlobalIdGenerator.generateAsString()valcustomerId=GlobalIdGenerator.generateAsString()valorderItem=OrderItem(GlobalIdGenerator.generateAsString(),GlobalIdGenerator.generateAsString(),BigDecimal.valueOf(10),10)valorderItems=listOf(orderItem)valinventoryService=object:InventoryService{overridefungetInventory(productId:String):Mono<Int>{returnorderItems.toFlux().filter{it.productId==productId}.map{it.quantity}.last()}}valpricingService=object:PricingService{overridefungetProductPrice(productId:String):Mono<BigDecimal>{returnorderItems.toFlux().filter{it.productId==productId}.map{it.price}.last()}}returnaggregateVerifier<Order,OrderState>(tenantId=tenantId).inject(DefaultCreateOrderSpec(inventoryService,pricingService)).given().`when`(CreateOrder(customerId,orderItems,SHIPPING_ADDRESS)).expectEventCount(1).expectEventType(OrderCreated::class.java).expectStateAggregate{assertThat(it.aggregateId.tenantId,equalTo(tenantId))}.expectState{assertThat(it.id,notNullValue())assertThat(it.customerId,equalTo(customerId))assertThat(it.address,equalTo(SHIPPING_ADDRESS))assertThat(it.items,equalTo(orderItems))assertThat(it.status,equalTo(OrderStatus.CREATED))}.verify()}/***创建订单*/@TestfuncreateOrder(){mockCreateOrder()}/***创建订单-库存不足*/@TestfuncreateOrderWhenInventoryShortage(){valcustomerId=GlobalIdGenerator.generateAsString()valorderItem=OrderItem(GlobalIdGenerator.generateAsString(),GlobalIdGenerator.generateAsString(),BigDecimal.valueOf(10),10)valorderItems=listOf(orderItem)valinventoryService=object:InventoryService{overridefungetInventory(productId:String):Mono<Int>{returnorderItems.toFlux().filter{it.productId==productId}/**模拟库存不足*/.map{it.quantity-1}.last()}}valpricingService=object:PricingService{overridefungetProductPrice(productId:String):Mono<BigDecimal>{returnorderItems.toFlux().filter{it.productId==productId}.map{it.price}.last()}}aggregateVerifier<Order,OrderState>().inject(DefaultCreateOrderSpec(inventoryService,pricingService)).given().`when`(CreateOrder(customerId,orderItems,SHIPPING_ADDRESS))/**期望:库存不足异常.*/.expectErrorType(InventoryShortageException::class.java).expectStateAggregate{/**该聚合对象处于未初始化状态,即该聚合未创建成功.*/assertThat(it.initialized,equalTo(false))}.verify()}/***创建订单-下单价格与当前价格不一致*/@TestfuncreateOrderWhenPriceInconsistency(){valcustomerId=GlobalIdGenerator.generateAsString()valorderItem=OrderItem(GlobalIdGenerator.generateAsString(),GlobalIdGenerator.generateAsString(),BigDecimal.valueOf(10),10)valorderItems=listOf(orderItem)valinventoryService=object:InventoryService{overridefungetInventory(productId:String):Mono<Int>{returnorderItems.toFlux().filter{it.productId==productId}.map{it.quantity}.last()}}valpricingService=object:PricingService{overridefungetProductPrice(productId:String):Mono<BigDecimal>{returnorderItems.toFlux().filter{it.productId==productId}/**模拟下单价格、商品定价不一致*/.map{it.price.plus(BigDecimal.valueOf(1))}.last()}}aggregateVerifier<Order,OrderState>().inject(DefaultCreateOrderSpec(inventoryService,pricingService)).given().`when`(CreateOrder(customerId,orderItems,SHIPPING_ADDRESS))/**期望:价格不一致异常.*/.expectErrorType(PriceInconsistencyException::class.java).verify()}privatefunmockPayOrder():VerifiedStage<OrderState>{valverifiedStageAfterCreateOrder=mockCreateOrder()valpreviousState=verifiedStageAfterCreateOrder.stateRootvalpayOrder=PayOrder(previousState.id,GlobalIdGenerator.generateAsString(),previousState.totalAmount)returnverifiedStageAfterCreateOrder.then().given()/**2.当接收到命令*/.`when`(payOrder)/**3.1期望将会产生1个事件*/.expectEventCount(1)/**3.2期望将会产生一个OrderPaid事件(3.1可以不需要)*/.expectEventType(OrderPaid::class.java)/**3.3期望产生的事件状态*/.expectEventBody<OrderPaid>{assertThat(it.amount,equalTo(payOrder.amount))}/**4.期望当前聚合状态*/.expectState{assertThat(it.address,equalTo(SHIPPING_ADDRESS))assertThat(it.paidAmount,equalTo(payOrder.amount))assertThat(it.status,equalTo(OrderStatus.PAID))}/**完成测试编排后,验证期望.*/.verify()}/***支付订单*/@TestfunpayOrder(){mockPayOrder()}/***支付订单-超付*/@TestfunpayOrderWhenOverPay(){valverifiedStageAfterCreateOrder=mockCreateOrder()valpreviousState=verifiedStageAfterCreateOrder.stateRootvalpayOrder=PayOrder(previousState.id,GlobalIdGenerator.generateAsString(),previousState.totalAmount.plus(BigDecimal.valueOf(1)))verifiedStageAfterCreateOrder.then().given()/**2.处理PayOrder命令*/.`when`(payOrder)/**3.1期望将会产生俩个事件分别是:OrderPaid、OrderOverPaid*/.expectEventType(OrderPaid::class.java,OrderOverPaid::class.java)/**3.2期望产生的事件状态*/.expectEventStream{valitr=it.iterator()/**OrderPaid*/valorderPaid=itr.next().bodyasOrderPaidassertThat(orderPaid.paid,equalTo(true))/**OrderOverPaid*/valorderOverPaid=itr.next().bodyasOrderOverPaidassertThat(orderOverPaid.overPay,equalTo(payOrder.amount.minus(previousState.totalAmount)))}/**4.期望当前聚合状态*/.expectState{assertThat(it.paidAmount,equalTo(previousState.totalAmount))assertThat(it.status,equalTo(OrderStatus.PAID))}.verify()}/***发货*/@Testfunship(){valverifiedStageAfterPayOrder=mockPayOrder()valshipOrder=ShipOrder(verifiedStageAfterPayOrder.stateRoot.id)verifiedStageAfterPayOrder.then().given().`when`(shipOrder).expectEventType(OrderShipped::class.java)/**4.期望当前聚合状态*/.expectState{assertThat(it.status,equalTo(OrderStatus.SHIPPED))}.verify()}@TestfunshipGivenUnpaid(){valverifiedStageAfterCreateOrder=mockCreateOrder()valshipOrder=ShipOrder(verifiedStageAfterCreateOrder.stateRoot.id)verifiedStageAfterCreateOrder.then().given().`when`(shipOrder).expectErrorType(IllegalStateException::class.java).expectState{/**验证聚合状态[未]发生变更.*/assertThat(it.paidAmount,equalTo(BigDecimal.ZERO))assertThat(it.status,equalTo(OrderStatus.CREATED))}.verify()}privatefunmockDeleteOrder():VerifiedStage<OrderState>{valverifiedStageAfterCreateOrder=mockCreateOrder()returnverifiedStageAfterCreateOrder.then().given().`when`(DeleteAggregate).expectEventType(AggregateDeleted::class.java).expectStateAggregate{assertThat(it.deleted,equalTo(true))}.verify()}@TestfundeleteOrder(){mockDeleteOrder()}@TestfundeleteGivenDeleted(){valverifiedStageAfterDelete=mockDeleteOrder()verifiedStageAfterDelete.then().given().`when`(DeleteAggregate).expectErrorType(IllegalAccessDeletedAggregateException::class.java).expectError<IllegalAccessDeletedAggregateException>{assertThat(it.aggregateId,equalTo(verifiedStageAfterDelete.stateAggregate.aggregateId))}.expectStateAggregate{assertThat(it.deleted,equalTo(true))}.verify()}}设计聚合建模SingleClassInheritancePatternAggregationPattern加载聚合

聚合状态流

发送命令

命令与事件流

Saga-OrderProcessManager(Demo)

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论