├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE └── workflows │ ├── codecov.yml │ ├── compensation-deploy.yml │ ├── compensation-test.yml │ ├── documentation-deploy.yml │ ├── example-deploy.yml │ ├── example-java-test.yml │ ├── gitee-sync.yml │ ├── integration-test.yml │ └── package-deploy.yml ├── .gitignore ├── .idea ├── .gitignore ├── Wow.iml ├── checkstyle-idea.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── copyright │ ├── ahoo_wang.xml │ └── profiles_settings.xml ├── dataSources.xml ├── detekt.xml ├── gradle.xml ├── httpClient.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── jsonSchemas.xml ├── kotlinc.xml ├── misc.xml ├── modules.xml ├── modules │ ├── Wow.iml │ ├── Wow.main.iml │ ├── compensation │ │ ├── wow-compensation-api │ │ │ ├── Wow.wow-compensation-api.iml │ │ │ ├── Wow.wow-compensation-api.main.iml │ │ │ └── Wow.wow-compensation-api.test.iml │ │ ├── wow-compensation-core │ │ │ └── Wow.wow-compensation-core.main.iml │ │ ├── wow-compensation-domain │ │ │ └── Wow.wow-compensation-domain.main.iml │ │ └── wow-compensation-server │ │ │ ├── Wow.wow-compensation-server.iml │ │ │ └── Wow.wow-compensation-server.test.iml │ ├── example │ │ ├── example-api │ │ │ ├── Wow.example-api.iml │ │ │ ├── Wow.example-api.main.iml │ │ │ └── Wow.example-api.test.iml │ │ ├── example-domain │ │ │ ├── Wow.example-domain.iml │ │ │ ├── Wow.example-domain.main.iml │ │ │ └── Wow.example-domain.test.iml │ │ ├── example-server │ │ │ ├── Wow.example-server.iml │ │ │ └── Wow.example-server.main.iml │ │ └── transfer │ │ │ ├── example-transfer-api │ │ │ ├── Wow.example-transfer-api.main.iml │ │ │ └── Wow.example-transfer-api.test.iml │ │ │ ├── example-transfer-domain │ │ │ ├── Wow.example-transfer-domain.main.iml │ │ │ └── Wow.example-transfer-domain.test.iml │ │ │ └── example-transfer-server │ │ │ └── Wow.example-transfer-server.main.iml │ ├── test │ │ ├── wow-mock │ │ │ └── Wow.wow-mock.iml │ │ ├── wow-tck │ │ │ ├── Wow.wow-tck.iml │ │ │ ├── Wow.wow-tck.main.iml │ │ │ ├── Wow.wow-tck.test.iml │ │ │ ├── me.ahoo.wow.Wow.wow-tck.main.iml │ │ │ └── me.ahoo.wow.Wow.wow-tck.test.iml │ │ └── wow-test │ │ │ ├── Wow.wow-test.test.iml │ │ │ └── me.ahoo.wow.Wow.wow-test.test.iml │ ├── wow-api │ │ ├── Wow.wow-api.iml │ │ ├── Wow.wow-api.main.iml │ │ └── Wow.wow-api.test.iml │ ├── wow-apiclient │ │ ├── Wow.wow-apiclient.iml │ │ └── Wow.wow-apiclient.main.iml │ ├── wow-bi │ │ └── Wow.wow-bi.iml │ ├── wow-bom │ │ └── Wow.wow-bom.iml │ ├── wow-cocache │ │ ├── Wow.wow-cocache.main.iml │ │ └── Wow.wow-cocache.test.iml │ ├── wow-compiler │ │ ├── Wow.wow-compiler.iml │ │ └── Wow.wow-compiler.main.iml │ ├── wow-core │ │ ├── Wow.wow-core.iml │ │ ├── Wow.wow-core.main.iml │ │ └── Wow.wow-core.test.iml │ ├── wow-dependencies │ │ └── Wow.wow-dependencies.iml │ ├── wow-elasticsearch │ │ ├── Wow.wow-elasticsearch.iml │ │ ├── Wow.wow-elasticsearch.main.iml │ │ └── Wow.wow-elasticsearch.test.iml │ ├── wow-it │ │ └── Wow.wow-it.iml │ ├── wow-kafka │ │ ├── Wow.wow-kafka.iml │ │ └── Wow.wow-kafka.main.iml │ ├── wow-models │ │ └── Wow.wow-models.main.iml │ ├── wow-mongo │ │ ├── Wow.wow-mongo.iml │ │ ├── Wow.wow-mongo.main.iml │ │ └── Wow.wow-mongo.test.iml │ ├── wow-openapi │ │ └── Wow.wow-openapi.main.iml │ ├── wow-opentelemetry │ │ ├── Wow.wow-opentelemetry.iml │ │ ├── Wow.wow-opentelemetry.main.iml │ │ └── Wow.wow-opentelemetry.test.iml │ ├── wow-query │ │ ├── Wow.wow-query.iml │ │ ├── Wow.wow-query.main.iml │ │ └── Wow.wow-query.test.iml │ ├── wow-r2dbc │ │ └── Wow.wow-r2dbc.iml │ ├── wow-redis │ │ └── Wow.wow-redis.iml │ ├── wow-schema │ │ └── Wow.wow-schema.test.iml │ ├── wow-spring-boot-starter │ │ ├── Wow.wow-spring-boot-starter.iml │ │ ├── Wow.wow-spring-boot-starter.main.iml │ │ └── Wow.wow-spring-boot-starter.test.iml │ ├── wow-spring │ │ ├── Wow.wow-spring.iml │ │ ├── Wow.wow-spring.main.iml │ │ └── Wow.wow-spring.test.iml │ └── wow-webflux │ │ ├── Wow.wow-webflux.iml │ │ ├── Wow.wow-webflux.main.iml │ │ └── Wow.wow-webflux.test.iml ├── sqldialects.xml ├── templateLanguages.xml ├── uiDesigner.xml └── vcs.xml ├── LICENSE ├── README.md ├── README.zh-CN.md ├── build.gradle.kts ├── codecov.yml ├── compensation ├── README.md ├── wow-compensation-api │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── compensation │ │ │ ├── CompensationService.kt │ │ │ └── api │ │ │ ├── ApplyExecutionFailed.kt │ │ │ ├── ApplyExecutionSuccess.kt │ │ │ ├── ApplyRetrySpec.kt │ │ │ ├── ChangeFunction.kt │ │ │ ├── CreateExecutionFailed.kt │ │ │ ├── IExecutionFailedState.kt │ │ │ ├── MarkRecoverable.kt │ │ │ └── PrepareCompensation.kt │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── compensation │ │ └── api │ │ └── query │ │ └── RetrySpecTest.kt ├── wow-compensation-core │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── compensation │ │ │ └── core │ │ │ ├── CompensationEventProcessor.kt │ │ │ └── CompensationFilter.kt │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── compensation │ │ └── core │ │ ├── CompensationEventProcessorTest.kt │ │ └── CompensationFilterTest.kt ├── wow-compensation-dashboard │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── angular.json │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── api │ │ │ │ ├── ApplyRetrySpec.ts │ │ │ │ ├── ChangeFunction.ts │ │ │ │ ├── CommandResult.ts │ │ │ │ ├── CompensationClient.ts │ │ │ │ ├── DomainEventStream.ts │ │ │ │ ├── EventStreamQuery.ts │ │ │ │ ├── ExecutionFailedState.ts │ │ │ │ ├── ListQuery.ts │ │ │ │ ├── MarkRecoverable.ts │ │ │ │ ├── PagedList.ts │ │ │ │ ├── PagedQuery.ts │ │ │ │ ├── Query.ts │ │ │ │ └── RetryConditions.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.scss │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.config.ts │ │ │ ├── app.routes.ts │ │ │ ├── apply-retry-spec │ │ │ │ ├── apply-retry-spec.component.html │ │ │ │ ├── apply-retry-spec.component.scss │ │ │ │ ├── apply-retry-spec.component.spec.ts │ │ │ │ └── apply-retry-spec.component.ts │ │ │ ├── error │ │ │ │ ├── error.component.html │ │ │ │ ├── error.component.scss │ │ │ │ ├── error.component.spec.ts │ │ │ │ └── error.component.ts │ │ │ ├── executing │ │ │ │ ├── executing.component.html │ │ │ │ ├── executing.component.scss │ │ │ │ ├── executing.component.spec.ts │ │ │ │ └── executing.component.ts │ │ │ ├── failed-history │ │ │ │ ├── failed-history.component.html │ │ │ │ ├── failed-history.component.scss │ │ │ │ ├── failed-history.component.spec.ts │ │ │ │ └── failed-history.component.ts │ │ │ ├── failed-list │ │ │ │ ├── failed-list.component.html │ │ │ │ ├── failed-list.component.scss │ │ │ │ ├── failed-list.component.spec.ts │ │ │ │ └── failed-list.component.ts │ │ │ ├── icons-provider.ts │ │ │ ├── next-retry │ │ │ │ ├── next-retry.component.html │ │ │ │ ├── next-retry.component.scss │ │ │ │ ├── next-retry.component.spec.ts │ │ │ │ └── next-retry.component.ts │ │ │ ├── non-retryable │ │ │ │ ├── non-retryable.component.html │ │ │ │ ├── non-retryable.component.scss │ │ │ │ ├── non-retryable.component.spec.ts │ │ │ │ └── non-retryable.component.ts │ │ │ ├── succeeded │ │ │ │ ├── succeeded.component.html │ │ │ │ ├── succeeded.component.scss │ │ │ │ ├── succeeded.component.spec.ts │ │ │ │ └── succeeded.component.ts │ │ │ ├── to-retry │ │ │ │ ├── to-retry.component.html │ │ │ │ ├── to-retry.component.scss │ │ │ │ ├── to-retry.component.spec.ts │ │ │ │ └── to-retry.component.ts │ │ │ └── unrecoverable │ │ │ │ ├── unrecoverable.component.html │ │ │ │ ├── unrecoverable.component.scss │ │ │ │ ├── unrecoverable.component.spec.ts │ │ │ │ └── unrecoverable.component.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ └── Logo-Full.svg │ │ ├── environments │ │ │ ├── environment.development.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── styles.scss │ │ └── theme.less │ ├── tsconfig.app.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── wow-compensation-domain │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── compensation │ │ │ └── domain │ │ │ ├── CompensationBoundedContext.kt │ │ │ ├── ExecutionFailed.kt │ │ │ ├── ExecutionFailedState.kt │ │ │ ├── FindNextRetry.kt │ │ │ └── NextRetryAtCalculator.kt │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── compensation │ │ └── domain │ │ ├── CommandSortTest.kt │ │ ├── DefaultNextRetryAtCalculatorTest.kt │ │ ├── ExecutionFailedStateTest.kt │ │ └── ExecutionFailedTest.kt └── wow-compensation-server │ ├── Dockerfile │ ├── build.gradle.kts │ └── src │ ├── dist │ ├── config │ │ └── application.yaml │ └── logs │ │ └── .gitignore │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── compensation │ │ │ └── server │ │ │ ├── CompensationServer.kt │ │ │ ├── configuration │ │ │ ├── CompensationConfiguration.kt │ │ │ └── CompensationProperties.kt │ │ │ ├── dashboard │ │ │ └── DashboardConfiguration.kt │ │ │ ├── failed │ │ │ └── SnapshotFindNextRetry.kt │ │ │ ├── scheduler │ │ │ ├── CompensationScheduler.kt │ │ │ ├── ConditionalOnSchedulerEnabled.kt │ │ │ ├── SchedulerConfiguration.kt │ │ │ └── SchedulerProperties.kt │ │ │ └── webhook │ │ │ ├── QuickNavigation.kt │ │ │ ├── TemplateEngine.kt │ │ │ └── weixin │ │ │ ├── ConditionalOnWeiXinWebHookEnabled.kt │ │ │ ├── WeiXinWebHook.kt │ │ │ ├── WeiXinWebHookConfiguration.kt │ │ │ ├── WeiXinWebHookProperties.kt │ │ │ └── client │ │ │ ├── WeiXinBotApi.kt │ │ │ └── WeiXinSendMessage.kt │ └── resources │ │ ├── application.yaml │ │ ├── banner.txt │ │ ├── indexs │ │ └── execution_failed_index.json │ │ └── jte │ │ ├── compensation_prepared.kte │ │ ├── execution_failed_applied.kte │ │ ├── execution_failed_created.kte │ │ ├── execution_success_applied.kte │ │ ├── layout.kte │ │ └── recoverable_marked.kte │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── compensation │ └── server │ ├── failed │ └── SnapshotFindNextRetryTest.kt │ └── webhook │ └── TemplateEngineTest.kt ├── config ├── detekt │ └── detekt.yml ├── logback-jmh.xml └── logback.xml ├── deploy ├── compensation │ ├── config-elasticsearch.yaml │ ├── config-redis-elasticsearch.yaml │ ├── config.yaml │ ├── deployment.yaml │ ├── hpa.yaml │ ├── init-schema.js │ └── service.yaml ├── example │ ├── config.yaml │ ├── deployment.yaml │ ├── hpa.yaml │ ├── perf │ │ ├── config │ │ │ ├── kafka_redis.yaml │ │ │ ├── mongo_kafka_redis.yaml │ │ │ └── redis.yaml │ │ ├── deployment.yaml │ │ ├── kafka.yaml │ │ ├── mongo.yaml │ │ ├── mongo_sharding.js │ │ ├── redis.yaml │ │ └── zookeeper.yaml │ ├── request │ │ ├── AddCartItem.http │ │ ├── CreateOrder.http │ │ └── http-client.env.json │ └── service.yaml └── script │ └── clickhouse.sql ├── document ├── design │ ├── assets │ │ ├── Aggregate-State-Flow.svg │ │ ├── Architecture.svg │ │ ├── CI-Flow.png │ │ ├── Command-Event-Flow.svg │ │ ├── Command-flow-and-command-processing.svg │ │ ├── Event-Compensation-UserCase.svg │ │ ├── Event-Compensation.svg │ │ ├── EventSourcing.svg │ │ ├── Features.png │ │ ├── Load-Aggregate.svg │ │ ├── Modeling-Aggregation-Pattern.svg │ │ ├── Modeling-Inheritance-Pattern.svg │ │ ├── Modeling-Single-Class-Pattern.svg │ │ ├── OpenAPI-Swagger.png │ │ ├── OpenTelemetry.png │ │ ├── Saga-Order.svg │ │ ├── Saga-Transfer.svg │ │ ├── Send-Command.svg │ │ ├── WOW-BI.png │ │ ├── compensation-dashboard-apply-retry-spec.png │ │ ├── compensation-dashboard-error.png │ │ ├── compensation-dashboard-succeeded.png │ │ ├── compensation-dashboard.png │ │ ├── example-transfer-jacoco.png │ │ ├── example-transfer-swagger.png │ │ └── logo.svg │ └── uml │ │ ├── Aggregate-Modeling.puml │ │ ├── Aggregate-State.puml │ │ ├── Architecture-diagram.puml │ │ ├── Command-Event-Flow.puml │ │ ├── Command-Feedback.puml │ │ ├── Compensation-State.puml │ │ ├── Event-Compensation-UserCase.puml │ │ ├── Event-Compensation.puml │ │ ├── Handler.puml │ │ ├── Load-Aggregate-Sequence-Diagram.puml │ │ ├── Naming.puml │ │ ├── Order-Process-Manager.puml │ │ ├── Send-Command.puml │ │ ├── Transfer-Process-Manager.puml │ │ ├── context-mapper.puml │ │ ├── eventbus-class.puml │ │ ├── layout.puml │ │ ├── message-class-diagram.puml │ │ └── message-subscriber-class.puml └── example │ ├── example-domain-jococo.png │ └── perf │ ├── Example.Cart.Add@PROCESSED.pdf │ ├── Example.Cart.Add@PROCESSED.png │ ├── Example.Cart.Add@SENT.pdf │ ├── Example.Cart.Add@SENT.png │ ├── Example.Order.Create@PROCESSED.pdf │ ├── Example.Order.Create@PROCESSED.png │ ├── Example.Order.Create@SENT.pdf │ └── Example.Order.Create@SENT.png ├── documentation ├── .gitignore ├── docs │ ├── .vitepress │ │ ├── config.mts │ │ ├── configs │ │ │ ├── SITE_BASE.ts │ │ │ ├── head.ts │ │ │ ├── navbar.ts │ │ │ └── sidebar.ts │ │ └── theme │ │ │ ├── global.css │ │ │ └── index.ts │ ├── guide │ │ ├── advanced │ │ │ ├── aggregate-scheduler.md │ │ │ ├── architecture.md │ │ │ ├── compiler.md │ │ │ ├── id-generator.md │ │ │ ├── metrics.md │ │ │ ├── observability.md │ │ │ └── prepare-key.md │ │ ├── best-practices.md │ │ ├── bi.md │ │ ├── command-gateway.md │ │ ├── configuration.md │ │ ├── event-compensation.md │ │ ├── event-processor.md │ │ ├── eventstore.md │ │ ├── extensions │ │ │ ├── elasticsearch.md │ │ │ ├── kafka.md │ │ │ ├── mongo.md │ │ │ ├── opentelemetry.md │ │ │ ├── r2bdc.md │ │ │ ├── redis.md │ │ │ ├── spring-boot-starter.md │ │ │ ├── tck.md │ │ │ └── webflux.md │ │ ├── getting-started.md │ │ ├── introduction.md │ │ ├── modeling.md │ │ ├── open-api.md │ │ ├── perf-test.md │ │ ├── projection.md │ │ ├── query.md │ │ ├── saga.md │ │ ├── snapshot.md │ │ └── test-suite.md │ ├── index.md │ ├── public │ │ ├── baidu_verify_codeva-ufKazSOGJx.html │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── Architecture.svg │ │ │ ├── Features.png │ │ │ ├── bi │ │ │ │ └── bi.svg │ │ │ ├── command-gateway │ │ │ │ └── send-command.svg │ │ │ ├── compensation │ │ │ │ ├── dashboard-apply-retry-spec.png │ │ │ │ ├── dashboard-error.png │ │ │ │ ├── dashboard-succeeded.png │ │ │ │ ├── dashboard-unrecoverable.png │ │ │ │ ├── dashboard.png │ │ │ │ ├── execution-failed.png │ │ │ │ ├── execution-success.png │ │ │ │ ├── open-api.png │ │ │ │ ├── process-sequence-diagram.svg │ │ │ │ ├── state-diagram.svg │ │ │ │ └── usercase.svg │ │ │ ├── eventstore │ │ │ │ └── eventsourcing.svg │ │ │ ├── example │ │ │ │ ├── transfer-jacoco.png │ │ │ │ ├── transfer-saga.svg │ │ │ │ └── transfer-swagger.png │ │ │ ├── getting-started │ │ │ │ ├── ci-flow.png │ │ │ │ ├── manage-project-templates.png │ │ │ │ ├── new-project.png │ │ │ │ ├── run-server.png │ │ │ │ ├── swagger-ui.png │ │ │ │ ├── test-coverage.png │ │ │ │ └── usecase.svg │ │ │ ├── logo.svg │ │ │ ├── modeling │ │ │ │ ├── aggregation-pattern.svg │ │ │ │ ├── inheritance-pattern.svg │ │ │ │ └── single-class-pattern.svg │ │ │ ├── observability │ │ │ │ └── observability.png │ │ │ ├── perf │ │ │ │ ├── Example.Cart.Add@PROCESSED.pdf │ │ │ │ ├── Example.Cart.Add@PROCESSED.png │ │ │ │ ├── Example.Cart.Add@SENT.pdf │ │ │ │ ├── Example.Cart.Add@SENT.png │ │ │ │ ├── Example.Order.Create@PROCESSED.pdf │ │ │ │ ├── Example.Order.Create@PROCESSED.png │ │ │ │ ├── Example.Order.Create@SENT.pdf │ │ │ │ └── Example.Order.Create@SENT.png │ │ │ ├── query │ │ │ │ └── open-api-query.png │ │ │ └── saga │ │ │ │ ├── choreography.png │ │ │ │ └── orchestration.png │ │ └── manifest.webmanifest │ └── reference │ │ ├── awesome │ │ ├── cqrs.md │ │ ├── microservices.md │ │ └── reactive.md │ │ ├── config │ │ ├── basic.md │ │ ├── command.md │ │ ├── event.md │ │ └── eventsourcing.md │ │ └── example │ │ ├── order.md │ │ └── transfer.md ├── package.json └── yarn.lock ├── example ├── example-api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── example │ │ └── api │ │ ├── ExampleService.kt │ │ ├── cart │ │ ├── AddCartItem.kt │ │ ├── CartItem.kt │ │ ├── ChangeQuantity.kt │ │ ├── ICartInfo.kt │ │ ├── MockVariableCommand.kt │ │ ├── MontedCommand.kt │ │ ├── RemoveCartItem.kt │ │ └── ViewCart.kt │ │ ├── client │ │ ├── CartQueryClient.kt │ │ └── CartQuerySyncClient.kt │ │ └── order │ │ ├── ChangeAddress.kt │ │ ├── CreateOrder.kt │ │ ├── OrderItem.kt │ │ ├── OrderPackage.kt │ │ ├── OrderProduct.kt │ │ ├── PayOrder.kt │ │ ├── ReceiptOrder.kt │ │ ├── ShipOrder.kt │ │ └── ShippingAddress.kt ├── example-domain │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── example │ │ │ └── domain │ │ │ ├── ExampleBoundedContext.kt │ │ │ ├── cart │ │ │ ├── Cart.kt │ │ │ ├── CartSaga.kt │ │ │ └── CartState.kt │ │ │ ├── disable │ │ │ └── DisabledRouteAggregate.kt │ │ │ └── order │ │ │ ├── CreateOrderSpec.kt │ │ │ ├── Order.kt │ │ │ ├── OrderSaga.kt │ │ │ ├── OrderState.kt │ │ │ ├── OrderStatus.kt │ │ │ └── infra │ │ │ ├── InventoryService.kt │ │ │ └── PricingService.kt │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── example │ │ └── domain │ │ ├── cart │ │ ├── CartSagaTest.kt │ │ └── CartTest.kt │ │ └── order │ │ ├── MainFixtures.kt │ │ ├── OrchestrationTest.kt │ │ ├── OrderFixture.kt │ │ ├── OrderSagaTest.kt │ │ └── OrderTest.kt ├── example-server │ ├── Dockerfile │ ├── build.gradle.kts │ └── src │ │ ├── dist │ │ ├── config │ │ │ └── application.yaml │ │ └── logs │ │ │ └── .gitignore │ │ ├── init-schema │ │ └── init-schema.js │ │ └── main │ │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── example │ │ │ └── server │ │ │ ├── ExampleServer.kt │ │ │ ├── cart │ │ │ ├── CartController.kt │ │ │ └── MountedCommandRewriter.kt │ │ │ ├── command │ │ │ └── CommandProxyController.kt │ │ │ ├── configuration │ │ │ └── AppConfiguration.kt │ │ │ └── order │ │ │ ├── OrderEventProcessor.kt │ │ │ ├── OrderMessageFunction.kt │ │ │ ├── OrderProjector.kt │ │ │ ├── OrderQueryController.kt │ │ │ └── OrderRepository.kt │ │ └── resources │ │ └── application.yaml └── transfer │ ├── README.md │ ├── Transfer.http │ ├── example-transfer-api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── example │ │ └── transfer │ │ ├── TransferService.java │ │ └── api │ │ ├── AccountCreated.java │ │ ├── AccountFrozen.java │ │ ├── AccountUnfrozen.java │ │ ├── AmountEntered.java │ │ ├── AmountLocked.java │ │ ├── AmountUnlocked.java │ │ ├── Confirm.java │ │ ├── Confirmed.java │ │ ├── CreateAccount.java │ │ ├── Entry.java │ │ ├── EntryFailed.java │ │ ├── FreezeAccount.java │ │ ├── LockAmount.java │ │ ├── Prepare.java │ │ ├── Prepared.java │ │ ├── UnfreezeAccount.java │ │ └── UnlockAmount.java │ ├── example-transfer-domain │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── example │ │ │ └── transfer │ │ │ └── domain │ │ │ ├── Account.java │ │ │ ├── AccountState.java │ │ │ ├── TransferBoundedContext.java │ │ │ └── TransferSaga.java │ │ └── test │ │ ├── java │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── example │ │ │ └── transfer │ │ │ └── domain │ │ │ ├── AccountTest.java │ │ │ ├── TransferBoundedContextTest.java │ │ │ └── TransferSagaTest.java │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── example │ │ └── transfer │ │ └── domain │ │ ├── AccountKTest.kt │ │ └── TransferSagaKTest.kt │ └── example-transfer-server │ ├── build.gradle.kts │ └── src │ ├── dist │ ├── config │ │ └── application.yaml │ └── logs │ │ └── .gitignore │ └── main │ ├── java │ └── me │ │ └── ahoo │ │ └── wow │ │ └── example │ │ └── transfer │ │ └── server │ │ └── TransferExampleServer.java │ └── resources │ └── application.yaml ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── renovate.json ├── schema ├── query │ ├── definitions.schema.json │ ├── list-query.schema.json │ ├── paged-query.schema.json │ └── single-query.schema.json └── wow-metadata.schema.json ├── settings.gradle.kts ├── test ├── code-coverage-report │ └── build.gradle.kts ├── wow-it │ ├── build.gradle.kts │ └── src │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── it │ │ └── KafkaMongoCommandDispatcher.kt ├── wow-mock │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── eventsourcing │ │ │ └── mock │ │ │ ├── DelayEventStore.kt │ │ │ └── DelaySnapshotRepository.kt │ │ └── test │ │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── eventsourcing │ │ └── mock │ │ ├── DelayEventStoreTest.kt │ │ └── DelaySnapshotRepositoryTest.kt ├── wow-tck │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── tck │ │ │ ├── command │ │ │ ├── CommandBusSpec.kt │ │ │ └── CommandGatewaySpec.kt │ │ │ ├── container │ │ │ ├── ElasticsearchLauncher.kt │ │ │ ├── KafkaLauncher.kt │ │ │ └── MongoLauncher.kt │ │ │ ├── event │ │ │ ├── DomainEventBusSpec.kt │ │ │ ├── DomainEventStreamSpec.kt │ │ │ └── MockDomainEventStreams.kt │ │ │ ├── eventsourcing │ │ │ ├── EventStoreSpec.kt │ │ │ ├── StateAggregateRepositorySpec.kt │ │ │ ├── snapshot │ │ │ │ ├── SnapshotRepositorySpec.kt │ │ │ │ └── SnapshotStrategySpec.kt │ │ │ └── state │ │ │ │ └── StateEventBusSpec.kt │ │ │ ├── messaging │ │ │ └── MessageBusSpec.kt │ │ │ ├── metrics │ │ │ └── LoggingMeterRegistryInitializer.kt │ │ │ ├── mock │ │ │ └── MockAggregate.kt │ │ │ ├── modeling │ │ │ ├── command │ │ │ │ └── CommandDispatcherSpec.kt │ │ │ └── state │ │ │ │ └── StateAggregateFactorySpec.kt │ │ │ ├── prepare │ │ │ └── PrepareKeySpec.kt │ │ │ ├── projection │ │ │ ├── MockProjector.kt │ │ │ └── ProjectionDispatcherSpec.kt │ │ │ └── query │ │ │ ├── EventStreamQueryServiceSpec.kt │ │ │ └── SnapshotQueryServiceSpec.kt │ │ └── resources │ │ └── META-INF │ │ └── wow-metadata.json └── wow-test │ ├── build.gradle.kts │ └── src │ └── main │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── test │ │ ├── AggregateVerifier.kt │ │ ├── SagaVerifier.kt │ │ ├── aggregate │ │ ├── DefaultAggregateVerifier.kt │ │ ├── GivenInitializationCommand.kt │ │ └── Stages.kt │ │ ├── id │ │ └── TestGlobalIdGeneratorFactory.kt │ │ ├── saga │ │ └── stateless │ │ │ ├── DefaultStatelessSagaVerifier.kt │ │ │ ├── GivenReadOnlyStateAggregate.kt │ │ │ └── Stages.kt │ │ └── validation │ │ └── TestValidator.kt │ └── resources │ └── META-INF │ └── services │ └── me.ahoo.wow.id.GlobalIdGeneratorFactory ├── wow-api ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── api │ │ │ ├── Copyable.kt │ │ │ ├── Identifier.kt │ │ │ ├── Ordered.kt │ │ │ ├── Version.kt │ │ │ ├── Wow.kt │ │ │ ├── annotation │ │ │ ├── AfterCommand.kt │ │ │ ├── AggregateId.kt │ │ │ ├── AggregateName.kt │ │ │ ├── AggregateRoot.kt │ │ │ ├── AggregateRoute.kt │ │ │ ├── AggregateVersion.kt │ │ │ ├── AllowCreate.kt │ │ │ ├── Blocking.kt │ │ │ ├── BoundedContext.kt │ │ │ ├── CommandRoute.kt │ │ │ ├── CreateAggregate.kt │ │ │ ├── Description.kt │ │ │ ├── EntityObject.kt │ │ │ ├── Event.kt │ │ │ ├── EventProcessor.kt │ │ │ ├── Name.kt │ │ │ ├── OnCommand.kt │ │ │ ├── OnError.kt │ │ │ ├── OnEvent.kt │ │ │ ├── OnMessage.kt │ │ │ ├── OnSourcing.kt │ │ │ ├── OnStateEvent.kt │ │ │ ├── Order.kt │ │ │ ├── OwnerId.kt │ │ │ ├── ProjectionProcessor.kt │ │ │ ├── Retry.kt │ │ │ ├── StatelessSaga.kt │ │ │ ├── Summary.kt │ │ │ ├── TenantId.kt │ │ │ ├── ValueObject.kt │ │ │ └── VoidCommand.kt │ │ │ ├── command │ │ │ ├── CommandId.kt │ │ │ ├── CommandMessage.kt │ │ │ ├── CommandResultAccessor.kt │ │ │ ├── DeleteAggregate.kt │ │ │ ├── RecoverAggregate.kt │ │ │ ├── RequestId.kt │ │ │ └── validation │ │ │ │ └── CommandValidator.kt │ │ │ ├── event │ │ │ ├── AggregateDeleted.kt │ │ │ ├── AggregateRecovered.kt │ │ │ ├── DomainEvent.kt │ │ │ ├── IgnoreSourcing.kt │ │ │ └── Revision.kt │ │ │ ├── exception │ │ │ ├── ErrorInfo.kt │ │ │ └── RecoverableType.kt │ │ │ ├── messaging │ │ │ ├── Header.kt │ │ │ ├── Message.kt │ │ │ ├── TopicKind.kt │ │ │ ├── function │ │ │ │ ├── FunctionInfo.kt │ │ │ │ ├── FunctionInfoCapable.kt │ │ │ │ ├── FunctionInfoData.kt │ │ │ │ └── FunctionKind.kt │ │ │ └── processor │ │ │ │ └── ProcessorInfo.kt │ │ │ ├── modeling │ │ │ ├── AggregateId.kt │ │ │ ├── AggregateIdCapable.kt │ │ │ ├── DeletedCapable.kt │ │ │ ├── EventIdCapable.kt │ │ │ ├── EventTimeCapable.kt │ │ │ ├── FirstEventTimeCapable.kt │ │ │ ├── FirstOperatorCapable.kt │ │ │ ├── MaterializeState.kt │ │ │ ├── NamedAggregate.kt │ │ │ ├── NamedTypedAggregate.kt │ │ │ ├── OperatorCapable.kt │ │ │ ├── OwnerId.kt │ │ │ ├── SnapshotTimeCapable.kt │ │ │ ├── StateCapable.kt │ │ │ ├── TenantId.kt │ │ │ └── TypedAggregate.kt │ │ │ ├── naming │ │ │ ├── DescriptionCapable.kt │ │ │ ├── EnabledCapable.kt │ │ │ ├── Materialized.kt │ │ │ ├── Named.kt │ │ │ ├── NamedBoundedContext.kt │ │ │ ├── QualifiedNamed.kt │ │ │ └── SummaryCapable.kt │ │ │ └── query │ │ │ ├── Condition.kt │ │ │ ├── ConditionCapable.kt │ │ │ ├── DeletionState.kt │ │ │ ├── DynamicDocument.kt │ │ │ ├── ListQuery.kt │ │ │ ├── MaterializedSnapshot.kt │ │ │ ├── MediumMaterializedSnapshot.kt │ │ │ ├── Operator.kt │ │ │ ├── PagedList.kt │ │ │ ├── PagedQuery.kt │ │ │ ├── ProjectionCapable.kt │ │ │ ├── Queryable.kt │ │ │ ├── RewritableCondition.kt │ │ │ ├── RewritableProjection.kt │ │ │ ├── SingleQuery.kt │ │ │ ├── SmallMaterializedSnapshot.kt │ │ │ └── SortCapable.kt │ └── resources │ │ └── META-INF │ │ └── wow-metadata.json │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── api │ ├── command │ └── DefaultDeleteAggregateTest.kt │ ├── messaging │ └── function │ │ └── FunctionInfoDataKtTest.kt │ └── query │ ├── MaterializedSnapshotTest.kt │ └── PagedListTest.kt ├── wow-apiclient ├── build.gradle.kts └── src │ └── main │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── apiclient │ │ ├── command │ │ ├── CommandRequest.kt │ │ ├── ReactiveRestCommandGateway.kt │ │ ├── RestCommandGateway.kt │ │ ├── RestCommandGatewayException.kt │ │ └── SyncRestCommandGateway.kt │ │ └── query │ │ ├── ReactiveSnapshotCountQueryApi.kt │ │ ├── ReactiveSnapshotListQueryApi.kt │ │ ├── ReactiveSnapshotPagedQueryApi.kt │ │ ├── ReactiveSnapshotQueryApi.kt │ │ ├── ReactiveSnapshotSingleQueryApi.kt │ │ ├── SnapshotCountQueryApi.kt │ │ ├── SnapshotListQueryApi.kt │ │ ├── SnapshotPagedQueryApi.kt │ │ ├── SnapshotQueryApi.kt │ │ ├── SnapshotSingleQueryApi.kt │ │ ├── SynchronousSnapshotCountQueryApi.kt │ │ ├── SynchronousSnapshotListQueryApi.kt │ │ ├── SynchronousSnapshotPagedQueryApi.kt │ │ ├── SynchronousSnapshotQueryApi.kt │ │ └── SynchronousSnapshotSingleQueryApi.kt │ └── resources │ └── META-INF │ └── wow-metadata.json ├── wow-bi ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── bi │ │ │ ├── MessageHeaderSqlType.kt │ │ │ ├── ScriptEngine.kt │ │ │ ├── ScriptTemplateEngine.kt │ │ │ └── expansion │ │ │ ├── SqlBuilder.kt │ │ │ ├── SqlTypeMapping.kt │ │ │ ├── StateExpansionScriptGenerator.kt │ │ │ ├── TableNaming.kt │ │ │ └── column │ │ │ ├── ArrayJoinColumn.kt │ │ │ ├── ArrayObjectColumn.kt │ │ │ ├── Column.kt │ │ │ ├── MetadataColumn.kt │ │ │ ├── SimpleArrayColumn.kt │ │ │ ├── SimpleMapColumn.kt │ │ │ ├── StatePropertyColumn.kt │ │ │ └── StringMapColumn.kt │ └── resources │ │ └── clickhouse │ │ ├── clear.kte │ │ ├── command.kte │ │ ├── global.kte │ │ ├── state-event.kte │ │ └── state-last.kte │ └── test │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── bi │ │ ├── ScriptEngineTest.kt │ │ └── expansion │ │ └── StateExpansionScriptGeneratorTest.kt │ └── resources │ ├── META-INF │ └── wow-metadata.json │ └── expected_bi_aggregate_script.sql ├── wow-bom └── build.gradle.kts ├── wow-cocache ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── cache │ │ ├── StateToCacheDataConverter.kt │ │ ├── refresh │ │ ├── EvictStateCacheRefresher.kt │ │ ├── SetStateCacheRefresher.kt │ │ └── StateCacheRefresher.kt │ │ └── source │ │ ├── LoadCacheSourceConfiguration.kt │ │ ├── QueryApiCacheSource.kt │ │ ├── QueryServiceCacheSource.kt │ │ └── StateCacheSource.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── cache │ ├── refresh │ ├── EvictStateCacheRefresherTest.kt │ └── SetStateCacheRefresherTest.kt │ └── source │ ├── QueryApiCacheSourceTest.kt │ └── QueryServiceCacheSourceTest.kt ├── wow-compiler ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── compiler │ │ │ ├── AggregateRootResolver.kt │ │ │ ├── metadata │ │ │ ├── BoundedContextResolver.kt │ │ │ ├── CommandAggregateRootResolver.kt │ │ │ ├── MetadataMerger.kt │ │ │ ├── MetadataSymbolProcessor.kt │ │ │ └── MetadataSymbolProcessorProvider.kt │ │ │ └── query │ │ │ ├── QuerySymbolProcessor.kt │ │ │ ├── QuerySymbolProcessorProvider.kt │ │ │ └── StateAggregateRootResolver.kt │ └── resources │ │ └── META-INF │ │ └── services │ │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider │ └── test │ ├── java │ └── me │ │ └── ahoo │ │ └── wow │ │ └── compiler │ │ ├── MockJavaBoundedContext.java │ │ └── MockJavaCompilerAggregate.java │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── compiler │ │ ├── Compiles.kt │ │ ├── MockBoundedContext.kt │ │ ├── MockCompilerAggregate.kt │ │ ├── SourceFiles.kt │ │ ├── metadata │ │ └── MetadataSymbolProcessorTest.kt │ │ └── query │ │ └── QuerySymbolProcessorTest.kt │ └── resources │ └── META-INF │ └── wow-metadata.json ├── wow-core ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── infra │ │ │ └── accessor │ │ │ └── method │ │ │ └── FastInvoke.java │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ ├── annotation │ │ │ ├── AnnotationPropertyAccessorParser.kt │ │ │ └── SortedByOrder.kt │ │ │ ├── command │ │ │ ├── CommandBus.kt │ │ │ ├── CommandExceptions.kt │ │ │ ├── CommandExchange.kt │ │ │ ├── CommandFactory.kt │ │ │ ├── CommandGateway.kt │ │ │ ├── CommandOperator.kt │ │ │ ├── CommandResult.kt │ │ │ ├── CommandResultCapable.kt │ │ │ ├── DefaultCommandGateway.kt │ │ │ ├── InMemoryCommandBus.kt │ │ │ ├── LocalFirstCommandBus.kt │ │ │ ├── SimpleCommandMessage.kt │ │ │ ├── annotation │ │ │ │ └── CommandMetadataParser.kt │ │ │ ├── factory │ │ │ │ ├── CommandBuilder.kt │ │ │ │ ├── CommandBuilderRewriter.kt │ │ │ │ ├── CommandMessageFactory.kt │ │ │ │ ├── RewriteNoCommandException.kt │ │ │ │ └── SimpleCommandMessageFactory.kt │ │ │ ├── metadata │ │ │ │ └── CommandMetadata.kt │ │ │ ├── validation │ │ │ │ ├── NoOpValidator.kt │ │ │ │ └── Validators.kt │ │ │ └── wait │ │ │ │ ├── CommandStage.kt │ │ │ │ ├── CommandWaitNotifier.kt │ │ │ │ ├── MonoCommandWaitNotifier.kt │ │ │ │ ├── NotifierFilters.kt │ │ │ │ ├── WaitSignal.kt │ │ │ │ ├── WaitStrategy.kt │ │ │ │ ├── WaitStrategyRegistrar.kt │ │ │ │ ├── WaitingFor.kt │ │ │ │ ├── WaitingForAfterProcessed.kt │ │ │ │ ├── WaitingForEventHandled.kt │ │ │ │ ├── WaitingForProcessed.kt │ │ │ │ ├── WaitingForProjected.kt │ │ │ │ ├── WaitingForSagaHandled.kt │ │ │ │ ├── WaitingForSent.kt │ │ │ │ └── WaitingForSnapshot.kt │ │ │ ├── configuration │ │ │ ├── AggregateSearcher.kt │ │ │ ├── MetadataSearcher.kt │ │ │ ├── ScopeSearcher.kt │ │ │ └── WowMetadata.kt │ │ │ ├── event │ │ │ ├── AbstractAggregateEventDispatcher.kt │ │ │ ├── AbstractEventDispatcher.kt │ │ │ ├── AggregateEventDispatcher.kt │ │ │ ├── AggregateStateEventDispatcher.kt │ │ │ ├── DomainEventBus.kt │ │ │ ├── DomainEventDispatcher.kt │ │ │ ├── DomainEventException.kt │ │ │ ├── DomainEventExchange.kt │ │ │ ├── DomainEventFactory.kt │ │ │ ├── DomainEventFunctionFilter.kt │ │ │ ├── DomainEventFunctionRegistrar.kt │ │ │ ├── DomainEventHandler.kt │ │ │ ├── DomainEventStream.kt │ │ │ ├── DomainEventStreamFactory.kt │ │ │ ├── EventStreamExchange.kt │ │ │ ├── InMemoryDomainEventBus.kt │ │ │ ├── LocalFirstDomainEventBus.kt │ │ │ ├── SimpleDomainEvent.kt │ │ │ ├── annotation │ │ │ │ ├── EventMetadataParser.kt │ │ │ │ └── EventProcessorParser.kt │ │ │ ├── compensation │ │ │ │ ├── DomainEventCompensator.kt │ │ │ │ └── StateEventCompensator.kt │ │ │ ├── metadata │ │ │ │ └── EventMetadata.kt │ │ │ └── upgrader │ │ │ │ ├── DroppedEvent.kt │ │ │ │ ├── EventUpgrader.kt │ │ │ │ ├── EventUpgraderFactory.kt │ │ │ │ └── MutableDomainEventRecord.kt │ │ │ ├── eventsourcing │ │ │ ├── AbstractEventStore.kt │ │ │ ├── AggregateIdScanner.kt │ │ │ ├── EventSourcingExceptions.kt │ │ │ ├── EventSourcingStateAggregateRepository.kt │ │ │ ├── EventStore.kt │ │ │ ├── EventStoreStateAggregateRepository.kt │ │ │ ├── InMemoryEventStore.kt │ │ │ ├── snapshot │ │ │ │ ├── AggregateSnapshotDispatcher.kt │ │ │ │ ├── InMemorySnapshotRepository.kt │ │ │ │ ├── SimpleSnapshotStrategy.kt │ │ │ │ ├── Snapshot.kt │ │ │ │ ├── SnapshotDispatcher.kt │ │ │ │ ├── SnapshotFunctionFilter.kt │ │ │ │ ├── SnapshotHandler.kt │ │ │ │ ├── SnapshotRepository.kt │ │ │ │ ├── SnapshotStrategy.kt │ │ │ │ └── VersionOffsetSnapshotStrategy.kt │ │ │ └── state │ │ │ │ ├── InMemoryStateEventBus.kt │ │ │ │ ├── LocalFirstStateEventBus.kt │ │ │ │ ├── SendStateEventFilter.kt │ │ │ │ ├── StateEvent.kt │ │ │ │ ├── StateEventBus.kt │ │ │ │ └── StateEventExchange.kt │ │ │ ├── exception │ │ │ ├── ErrorCodes.kt │ │ │ ├── ErrorConverter.kt │ │ │ ├── ErrorConverterRegistrar.kt │ │ │ ├── NotFoundResourceException.kt │ │ │ ├── Preconditions.kt │ │ │ ├── RecoverableExceptionRegistrar.kt │ │ │ └── WowException.kt │ │ │ ├── filter │ │ │ ├── ErrorAccessor.kt │ │ │ ├── Filter.kt │ │ │ ├── FilterChain.kt │ │ │ ├── FilterChainBuilder.kt │ │ │ └── Handler.kt │ │ │ ├── id │ │ │ ├── AggregateIdGenerator.kt │ │ │ ├── AggregateIdGeneratorFactory.kt │ │ │ ├── CosIdAggregateIdGeneratorFactory.kt │ │ │ ├── CosIdGlobalIdGeneratorFactory.kt │ │ │ ├── GlobalIdGenerator.kt │ │ │ └── GlobalIdGeneratorFactory.kt │ │ │ ├── infra │ │ │ ├── Decorator.kt │ │ │ ├── Strings.kt │ │ │ ├── TypeNameMapper.kt │ │ │ ├── accessor │ │ │ │ ├── Accessor.kt │ │ │ │ ├── constructor │ │ │ │ ├── function │ │ │ │ │ ├── FunctionAccessor.kt │ │ │ │ │ ├── SimpleFunctionAccessor.kt │ │ │ │ │ └── reactive │ │ │ │ │ │ ├── BlockingMonoFunctionAccessor.kt │ │ │ │ │ │ ├── FluxMonoFunctionAccessor.kt │ │ │ │ │ │ ├── MonoFunctionAccessorFactory.kt │ │ │ │ │ │ ├── PublisherMonoFunctionAccessor.kt │ │ │ │ │ │ ├── ReactiveMethodAccessor.kt │ │ │ │ │ │ ├── SimpleMonoFunctionAccessor.kt │ │ │ │ │ │ └── SyncMonoFunctionAccessor.kt │ │ │ │ └── property │ │ │ │ │ ├── PropertyDescriptor.kt │ │ │ │ │ ├── PropertyGetter.kt │ │ │ │ │ └── PropertySetter.kt │ │ │ ├── idempotency │ │ │ │ ├── AggregateIdempotencyCheckerProvider.kt │ │ │ │ ├── BloomFilterIdempotencyChecker.kt │ │ │ │ └── IdempotencyChecker.kt │ │ │ ├── prepare │ │ │ │ ├── DefaultPreparedValue.kt │ │ │ │ ├── PrepareKey.kt │ │ │ │ ├── PrepareKeyFactory.kt │ │ │ │ └── PreparedValue.kt │ │ │ └── reflection │ │ │ │ ├── AnnotationScanner.kt │ │ │ │ ├── ClassMetadata.kt │ │ │ │ ├── ClassVisitor.kt │ │ │ │ ├── IntimateAnnotationElement.kt │ │ │ │ ├── MergedAnnotation.kt │ │ │ │ └── VisitorLifeCycle.kt │ │ │ ├── ioc │ │ │ ├── ServiceProvider.kt │ │ │ └── SimpleServiceProvider.kt │ │ │ ├── messaging │ │ │ ├── DefaultHeader.kt │ │ │ ├── InMemoryMessageBus.kt │ │ │ ├── LocalFirstMessageBus.kt │ │ │ ├── MessageBus.kt │ │ │ ├── MessageDispatcher.kt │ │ │ ├── ReceiverGroup.kt │ │ │ ├── compensation │ │ │ │ ├── CompensationMatcher.kt │ │ │ │ ├── EventCompensateSupporter.kt │ │ │ │ └── EventCompensator.kt │ │ │ ├── dispatcher │ │ │ │ ├── AbstractDispatcher.kt │ │ │ │ ├── AbstractMessageDispatcher.kt │ │ │ │ ├── AggregateMessageDispatcher.kt │ │ │ │ ├── MessageParallelism.kt │ │ │ │ └── SafeSubscriber.kt │ │ │ ├── function │ │ │ │ ├── ErrorMessageHandler.kt │ │ │ │ ├── FunctionAccessorMetadata.kt │ │ │ │ ├── FunctionMetadataParser.kt │ │ │ │ ├── MessageFunction.kt │ │ │ │ ├── MessageFunctionAccessor.kt │ │ │ │ ├── MessageFunctionRegistrar.kt │ │ │ │ └── SimpleMessageFunctionRegistrar.kt │ │ │ ├── handler │ │ │ │ ├── ExchangeAck.kt │ │ │ │ ├── ExchangeFilter.kt │ │ │ │ ├── MessageExchange.kt │ │ │ │ └── RetryableFilter.kt │ │ │ ├── processor │ │ │ │ ├── MessageProcessor.kt │ │ │ │ ├── ProcessorMetadata.kt │ │ │ │ └── ProcessorMetadataParser.kt │ │ │ └── propagation │ │ │ │ ├── CommandOperatorMessagePropagator.kt │ │ │ │ ├── CommandRequestHeaderPropagator.kt │ │ │ │ ├── MessagePropagator.kt │ │ │ │ ├── MessagePropagatorProvider.kt │ │ │ │ ├── TraceMessagePropagator.kt │ │ │ │ └── WaitStrategyMessagePropagator.kt │ │ │ ├── metadata │ │ │ ├── CacheableMetadataParser.kt │ │ │ └── Metadata.kt │ │ │ ├── metrics │ │ │ ├── AbstractMetricDecorator.kt │ │ │ ├── MetricCommandBus.kt │ │ │ ├── MetricCommandHandler.kt │ │ │ ├── MetricDomainEventBus.kt │ │ │ ├── MetricDomainEventHandler.kt │ │ │ ├── MetricEventStore.kt │ │ │ ├── MetricProjectionHandler.kt │ │ │ ├── MetricSnapshotHandler.kt │ │ │ ├── MetricSnapshotRepository.kt │ │ │ ├── MetricSnapshotStrategy.kt │ │ │ ├── MetricStateEventBus.kt │ │ │ ├── MetricStatelessSagaHandler.kt │ │ │ ├── Metrics.kt │ │ │ └── Metrizable.kt │ │ │ ├── modeling │ │ │ ├── DefaultAggregateId.kt │ │ │ ├── MaterializedNamedAggregate.kt │ │ │ ├── annotation │ │ │ │ ├── AggregateMetadataParser.kt │ │ │ │ └── StateAggregateMetadataParser.kt │ │ │ ├── command │ │ │ │ ├── AbstractCommandFunction.kt │ │ │ │ ├── AggregateCommandDispatcher.kt │ │ │ │ ├── AggregateProcessor.kt │ │ │ │ ├── AggregateProcessorFactory.kt │ │ │ │ ├── AggregateProcessorFilter.kt │ │ │ │ ├── CommandAggregate.kt │ │ │ │ ├── CommandAggregateExceptions.kt │ │ │ │ ├── CommandAggregateFactory.kt │ │ │ │ ├── CommandDispatcher.kt │ │ │ │ ├── CommandFunction.kt │ │ │ │ ├── CommandHandler.kt │ │ │ │ ├── DefaultDeleteAggregateFunction.kt │ │ │ │ ├── DefaultRecoverAggregateFunction.kt │ │ │ │ ├── ExchangeCommandAggregate.kt │ │ │ │ ├── RetryableAggregateProcessor.kt │ │ │ │ ├── SendDomainEventStreamFilter.kt │ │ │ │ ├── SimpleCommandAggregate.kt │ │ │ │ ├── SimpleCommandAggregateFactory.kt │ │ │ │ └── after │ │ │ │ │ ├── AfterCommandFunction.kt │ │ │ │ │ └── AfterCommandFunctionMetadata.kt │ │ │ ├── matedata │ │ │ │ ├── AggregateMetadata.kt │ │ │ │ ├── CommandAggregateMetadata.kt │ │ │ │ ├── NamedAggregateGetter.kt │ │ │ │ └── StateAggregateMetadata.kt │ │ │ └── state │ │ │ │ ├── ReadOnlyStateAggregate.kt │ │ │ │ ├── ReadOnlyStateAggregateAware.kt │ │ │ │ ├── SimpleStateAggregate.kt │ │ │ │ ├── SourcingVersionConflictException.kt │ │ │ │ ├── StateAggregate.kt │ │ │ │ ├── StateAggregateFactory.kt │ │ │ │ └── StateAggregateRepository.kt │ │ │ ├── naming │ │ │ ├── CurrentBoundedContext.kt │ │ │ ├── CurrentContextCapable.kt │ │ │ ├── MaterializedNamedBoundedContext.kt │ │ │ ├── NamingConverter.kt │ │ │ ├── NamingStrategy.kt │ │ │ └── annotation │ │ │ │ └── PascalToSnakeConverter.kt │ │ │ ├── projection │ │ │ ├── ProjectionDispatcher.kt │ │ │ ├── ProjectionFunctionFilter.kt │ │ │ ├── ProjectionFunctionRegistrar.kt │ │ │ ├── ProjectionHandler.kt │ │ │ └── annotation │ │ │ │ └── ProjectionProcessorMetadataParser.kt │ │ │ ├── saga │ │ │ ├── annotation │ │ │ │ ├── SagaAnnotations.kt │ │ │ │ └── StatelessSagaMetadataParser.kt │ │ │ ├── metadata │ │ │ │ └── SagaMetadata.kt │ │ │ ├── stateful │ │ │ │ ├── SagaManager.kt │ │ │ │ ├── SagaRepository.kt │ │ │ │ └── StatefulSaga.kt │ │ │ └── stateless │ │ │ │ ├── CommandStream.kt │ │ │ │ ├── ExchangeCommandStream.kt │ │ │ │ ├── StatelessSagaDispatcher.kt │ │ │ │ ├── StatelessSagaFunction.kt │ │ │ │ ├── StatelessSagaFunctionFilter.kt │ │ │ │ ├── StatelessSagaFunctionRegistrar.kt │ │ │ │ └── StatelessSagaHandler.kt │ │ │ ├── scheduler │ │ │ └── AggregateSchedulerSupplier.kt │ │ │ ├── serialization │ │ │ ├── AggregateIdJsonSerializer.kt │ │ │ ├── JsonMessageRecord.kt │ │ │ ├── JsonSerializer.kt │ │ │ ├── MessageSerializer.kt │ │ │ ├── WowModule.kt │ │ │ ├── command │ │ │ │ ├── CommandJsonSerializer.kt │ │ │ │ └── CommandRecord.kt │ │ │ ├── event │ │ │ │ ├── AbstractEventStreamJsonSerializer.kt │ │ │ │ ├── DomainEventJsonSerializer.kt │ │ │ │ ├── DomainEventRecord.kt │ │ │ │ ├── EventStreamJsonSerializer.kt │ │ │ │ ├── EventStreamRecord.kt │ │ │ │ ├── JsonDomainEvent.kt │ │ │ │ ├── StateEventJsonSerializer.kt │ │ │ │ └── StateRecord.kt │ │ │ └── state │ │ │ │ ├── AbstractStateAggregateSerializer.kt │ │ │ │ ├── SnapshotSerializer.kt │ │ │ │ └── StateAggregateSerializer.kt │ │ │ └── sharding │ │ │ ├── AggregateIdSharding.kt │ │ │ └── ShardingRegistrar.kt │ └── resources │ │ └── META-INF │ │ ├── services │ │ ├── com.fasterxml.jackson.databind.Module │ │ ├── me.ahoo.wow.id.AggregateIdGeneratorFactory │ │ ├── me.ahoo.wow.id.GlobalIdGeneratorFactory │ │ └── me.ahoo.wow.messaging.propagation.MessagePropagator │ │ └── wow-metadata.json │ └── test │ ├── java │ └── me │ │ └── ahoo │ │ └── wow │ │ └── infra │ │ ├── accessor │ │ └── function │ │ │ └── FastInvokeTest.java │ │ └── reflection │ │ ├── JvmRepeatableTag.java │ │ ├── JvmRepeatableTags.java │ │ └── MockRepeatableClass.java │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ ├── VersionTest.kt │ │ ├── WowTest.kt │ │ ├── annotation │ │ ├── AnnotationPropertyAccessorParserTest.kt │ │ └── SortedByOrderKtTest.kt │ │ ├── command │ │ ├── CommandFactoryTest.kt │ │ ├── CommandOperatorTest.kt │ │ ├── CommandResultExceptionTest.kt │ │ ├── CommandResultTest.kt │ │ ├── CommandValidationExceptionTest.kt │ │ ├── DefaultCommandGatewayTest.kt │ │ ├── DefaultCommandTest.kt │ │ ├── InMemoryCommandBusTest.kt │ │ ├── LocalFirstCommandBusTest.kt │ │ ├── MockCommands.kt │ │ ├── SimpleCommandMessageTest.kt │ │ ├── SimpleServerCommandExchangeTest.kt │ │ ├── annotation │ │ │ └── CommandMetadataParserTest.kt │ │ ├── factory │ │ │ ├── BlockingCommandBuilderRewriterTest.kt │ │ │ ├── MutableCommandBuilderTest.kt │ │ │ ├── SimpleCommandBuilderRewriterRegistryTest.kt │ │ │ └── SimpleCommandMessageFactoryTest.kt │ │ ├── metadata │ │ │ └── CommandMetadataTest.kt │ │ ├── validation │ │ │ ├── NoOpValidatorTest.kt │ │ │ └── ValidatorsKtTest.kt │ │ └── wait │ │ │ ├── CommandStageTest.kt │ │ │ ├── CommandWaitNotifierKtTest.kt │ │ │ ├── EventHandledNotifierFilterTest.kt │ │ │ ├── LocalCommandWaitNotifierTest.kt │ │ │ ├── MonoCommandWaitNotifierTest.kt │ │ │ ├── ProcessedNotifierFilterTest.kt │ │ │ ├── ProjectedNotifierFilterTest.kt │ │ │ ├── SagaHandledNotifierFilterTest.kt │ │ │ ├── SimpleWaitStrategyRegistrarTest.kt │ │ │ └── WaitingForTest.kt │ │ ├── configuration │ │ ├── AggregateTest.kt │ │ ├── BoundedContextTest.kt │ │ ├── MetadataSearcherTest.kt │ │ ├── NamedBoundedContextTest.kt │ │ └── WowMetadataTest.kt │ │ ├── event │ │ ├── DomainEventDispatcherTest.kt │ │ ├── DomainEventStreamFactoryKtTest.kt │ │ ├── DomainEventStreamTest.kt │ │ ├── ExchangeEventFunctionKtTest.kt │ │ ├── InMemoryDomainEventBusTest.kt │ │ ├── LocalFirstDomainEventBusTest.kt │ │ ├── MockEvents.kt │ │ ├── NoOpDomainEventBusTest.kt │ │ ├── annotation │ │ │ ├── EventMetadataParserTest.kt │ │ │ └── EventProcessorParserTest.kt │ │ ├── compensation │ │ │ ├── DomainEventCompensatorTest.kt │ │ │ └── StateEventCompensatorTest.kt │ │ └── upgrader │ │ │ ├── EventUpgraderFactoryTest.kt │ │ │ ├── MockEventChangeRevisionUpgrader.kt │ │ │ └── MockEventToDroppedUpgrader.kt │ │ ├── eventsourcing │ │ ├── AggregateIdScannerTest.kt │ │ ├── EventSourcingStateAggregateRepositoryTest.kt │ │ ├── EventStoreStateAggregateRepositoryTest.kt │ │ ├── InMemoryEventStoreTest.kt │ │ ├── SimpleDomainEventStreamTest.kt │ │ ├── snapshot │ │ │ ├── InMemorySnapshotRepositoryTest.kt │ │ │ ├── SimpleSnapshotStrategyTest.kt │ │ │ ├── SnapshotDispatcherTest.kt │ │ │ ├── SnapshotKtTest.kt │ │ │ └── VersionOffsetSnapshotStrategyTest.kt │ │ └── state │ │ │ ├── InMemoryStateEventBusTest.kt │ │ │ ├── LocalFirstStateEventBusTest.kt │ │ │ └── SendStateEventFilterTest.kt │ │ ├── exception │ │ ├── ErrorConverterRegistrarTest.kt │ │ ├── NotFoundResourceExceptionTest.kt │ │ ├── PreconditionsTest.kt │ │ ├── RecoverableExceptionRegistrarTest.kt │ │ └── WowExceptionTest.kt │ │ ├── filter │ │ ├── AbstractHandlerTest.kt │ │ ├── FilterChainBuilderTest.kt │ │ ├── LogErrorHandlerTest.kt │ │ └── LogResumeErrorHandlerTest.kt │ │ ├── id │ │ ├── AggregateIdGeneratorRegistrarTest.kt │ │ ├── CosIdAggregateIdGeneratorFactoryTest.kt │ │ ├── CosIdGlobalIdGeneratorFactoryTest.kt │ │ └── GlobalIdGeneratorTest.kt │ │ ├── infra │ │ ├── accessor │ │ │ ├── constructor │ │ │ ├── function │ │ │ │ ├── FunctionAccessorKtTest.kt │ │ │ │ ├── SimpleFunctionAccessorTest.kt │ │ │ │ └── reactive │ │ │ │ │ ├── BlockingMonoFunctionAccessorTest.kt │ │ │ │ │ └── MonoFunctionAccessorFactoryTest.kt │ │ │ └── property │ │ │ │ └── PropertyDescriptorTest.kt │ │ ├── idempotency │ │ │ ├── BloomFilterIdempotencyCheckerTest.kt │ │ │ └── NoOpIdempotencyCheckerTest.kt │ │ └── reflection │ │ │ ├── AnnotationScannerTest.kt │ │ │ ├── ClassMetadataTest.kt │ │ │ ├── IntimateAnnotationElementTest.kt │ │ │ └── MergedAnnotationTest.kt │ │ ├── ioc │ │ └── SimpleServiceProviderTest.kt │ │ ├── jackson │ │ ├── JacksonTest.kt │ │ └── Type.kt │ │ ├── messaging │ │ ├── DefaultHeaderTest.kt │ │ ├── HeaderTest.kt │ │ ├── compensation │ │ │ ├── CompensationMatcherTest.kt │ │ │ └── EventCompensateSupporterTest.kt │ │ ├── dispatcher │ │ │ ├── AbstractMessageDispatcherTest.kt │ │ │ └── SafeSubscriberTest.kt │ │ ├── function │ │ │ ├── FunctionMetadataParserTest.kt │ │ │ ├── MethodMessageFunctionTest.kt │ │ │ ├── MockFunctions.kt │ │ │ └── SimpleMessageFunctionRegistrarTest.kt │ │ ├── handler │ │ │ ├── ExchangeAckTest.kt │ │ │ └── RetryableExchangeFilterTest.kt │ │ └── propagation │ │ │ ├── CommandOperatorMessagePropagatorTest.kt │ │ │ ├── CommandRequestHeaderPropagatorTest.kt │ │ │ ├── MessagePropagatorProviderTest.kt │ │ │ ├── TraceMessagePropagatorTest.kt │ │ │ └── WaitStrategyMessagePropagatorTest.kt │ │ ├── modeling │ │ ├── AggregateIdTest.kt │ │ ├── NamedAggregateTest.kt │ │ ├── annotation │ │ │ ├── AggregateMetadataParserTest.kt │ │ │ └── MockAggregates.kt │ │ ├── command │ │ │ ├── CommandFunctionTest.kt │ │ │ ├── CommandStateTest.kt │ │ │ ├── DefaultDeleteAggregateFunctionTest.kt │ │ │ ├── ExchangeCommandAggregateKtTest.kt │ │ │ ├── InMemoryCommandDispatcherTest.kt │ │ │ ├── MockDelayEventStoreCommandDispatcherTest.kt │ │ │ ├── RetryableAggregateProcessorTest.kt │ │ │ ├── SimpleCommandAggregateTest.kt │ │ │ └── after │ │ │ │ └── AfterCommandFunctionMetadataTest.kt │ │ ├── matedata │ │ │ ├── AggregateMetadataTest.kt │ │ │ ├── CommandAggregateMetadataTest.kt │ │ │ └── SimpleNamedAggregateGetterTest.kt │ │ └── state │ │ │ ├── ConstructorStateAggregateFactoryTest.kt │ │ │ ├── SimpleStateAggregateTest.kt │ │ │ └── StateAggregatesTest.kt │ │ ├── naming │ │ ├── AppendPrefixNamingConverterTest.kt │ │ ├── AppendSuffixNamingConverterTest.kt │ │ ├── CamelCaseStrategyTest.kt │ │ ├── CompositeNamingConverterTest.kt │ │ ├── IgnorePrefixNamingConverterTest.kt │ │ ├── IgnoreSuffixNamingConverterTest.kt │ │ ├── KebabCaseStrategyTest.kt │ │ ├── LowerDotCaseStrategyTest.kt │ │ ├── MaterializedNamedBoundedContextTest.kt │ │ ├── NamingConverterTest.kt │ │ ├── PascalCaseStrategyTest.kt │ │ └── SnakeCaseStrategyTest.kt │ │ ├── projection │ │ ├── ProjectionDispatcherTest.kt │ │ ├── ProjectionHandlerRegistrarTest.kt │ │ └── annotation │ │ │ └── ProjectionProcessorMetadataParserTest.kt │ │ ├── reactor │ │ ├── RetryTest.kt │ │ └── SchedulerTest.kt │ │ ├── saga │ │ └── stateless │ │ │ ├── ExchangeCommandStreamKtTest.kt │ │ │ ├── StatelessSagaFunctionRegistrarTest.kt │ │ │ └── StatelessSagaFunctionTest.kt │ │ ├── serialization │ │ ├── JsonSerializerTest.kt │ │ └── event │ │ │ └── StateJsonRecordTest.kt │ │ └── sharding │ │ ├── CompositeAggregateIdShardingTest.kt │ │ ├── CosIdShardingDecoratorTest.kt │ │ └── SingleAggregateIdShardingTest.kt │ └── resources │ ├── META-INF │ ├── services │ │ ├── me.ahoo.wow.event.upgrader.EventUpgrader │ │ └── me.ahoo.wow.exception.ErrorConverterFactory │ └── wow-metadata.json │ └── junit-platform.properties ├── wow-dependencies └── build.gradle.kts ├── wow-elasticsearch ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── elasticsearch │ │ │ ├── IndexNameConverter.kt │ │ │ ├── IndexTemplateInitializer.kt │ │ │ ├── WowJsonpMapper.kt │ │ │ ├── eventsourcing │ │ │ ├── ElasticsearchEventStore.kt │ │ │ └── ElasticsearchSnapshotRepository.kt │ │ │ └── query │ │ │ ├── AbstractElasticsearchConditionConverter.kt │ │ │ ├── AbstractElasticsearchQueryService.kt │ │ │ ├── ElasticsearchProjectionConverter.kt │ │ │ ├── ElasticsearchSortConverter.kt │ │ │ ├── event │ │ │ ├── ElasticsearchEventStreamQueryService.kt │ │ │ ├── ElasticsearchEventStreamQueryServiceFactory.kt │ │ │ └── EventStreamConditionConverter.kt │ │ │ └── snapshot │ │ │ ├── ElasticsearchSnapshotQueryService.kt │ │ │ ├── ElasticsearchSnapshotQueryServiceFactory.kt │ │ │ └── SnapshotConditionConverter.kt │ └── resources │ │ └── templates │ │ ├── wow-event-stream-template.json │ │ └── wow-snapshot-template.json │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── elasticsearch │ ├── TemplateInitializer.kt │ ├── eventsourcing │ ├── ElasticsearchEventStoreTest.kt │ └── ElasticsearchSnapshotRepositoryTest.kt │ └── query │ ├── ElasticsearchConditionConverterTest.kt │ ├── ElasticsearchProjectionConverterTest.kt │ ├── ElasticsearchSortConverterTest.kt │ ├── event │ ├── ElasticsearchEventStreamQueryServiceTest.kt │ └── EventStreamConditionConverterTest.kt │ └── snapshot │ └── ElasticsearchSnapshotQueryServiceTest.kt ├── wow-kafka ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── kafka │ │ ├── AbstractKafkaBus.kt │ │ ├── AggregateTopicConverter.kt │ │ ├── KafkaCommandBus.kt │ │ ├── KafkaDomainEventBus.kt │ │ ├── KafkaEventStreamExchange.kt │ │ ├── KafkaServerCommandExchange.kt │ │ ├── KafkaStateEventBus.kt │ │ ├── KafkaStateEventExchange.kt │ │ └── ReceiverOptionsCustomizer.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── kafka │ ├── DefaultCommandTopicConverterTest.kt │ ├── DefaultEventStreamTopicConverterTest.kt │ ├── DefaultStateEventTopicConverterTest.kt │ ├── KafkaCommandBusTest.kt │ ├── KafkaCommandDispatcherTest.kt │ ├── KafkaDomainEventBusTest.kt │ └── KafkaStateEventBusTest.kt ├── wow-models ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── models │ │ ├── common │ │ ├── CompletedCapable.kt │ │ ├── ItemIdCapable.kt │ │ ├── NotBlankNameCapable.kt │ │ ├── QuantityCapable.kt │ │ ├── ReasonCapable.kt │ │ ├── RemarkCapable.kt │ │ └── TypeCapable.kt │ │ └── tree │ │ ├── Flat.kt │ │ ├── ITreeState.kt │ │ ├── Info.kt │ │ ├── Leaf.kt │ │ ├── Trees.kt │ │ ├── aggregate │ │ ├── Tree.kt │ │ └── TreeState.kt │ │ └── command │ │ ├── Create.kt │ │ ├── Delete.kt │ │ ├── Move.kt │ │ └── Update.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── models │ ├── common │ ├── CompletedCapableTest.kt │ ├── ItemIdCapableTest.kt │ ├── NotBlankNameCapableTest.kt │ ├── QuantityCapableTest.kt │ ├── ReasonCapableTest.kt │ ├── RemarkCapableTest.kt │ └── TypeCapableTest.kt │ └── tree │ ├── CategoryContext.kt │ ├── FlatCategory.kt │ ├── LeafCategory.kt │ ├── TreesTest.kt │ ├── aggregate │ ├── Category.kt │ └── CategoryState.kt │ ├── command │ ├── CreateCategory.kt │ ├── DeleteCategory.kt │ ├── MoveCategory.kt │ └── UpdateCategory.kt │ └── test │ └── CategoryTest.kt ├── wow-mongo ├── build.gradle.kts └── src │ ├── init-schema │ └── init-schema.js │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── mongo │ │ ├── AggregateSchemaInitializer.kt │ │ ├── Documents.kt │ │ ├── EventStreamSchemaInitializer.kt │ │ ├── MongoEventStore.kt │ │ ├── MongoSnapshotRepository.kt │ │ ├── SnapshotSchemaInitializer.kt │ │ ├── prepare │ │ ├── MongoPrepareKey.kt │ │ └── MongoPrepareKeyFactory.kt │ │ └── query │ │ ├── AbstractMongoConditionConverter.kt │ │ ├── AbstractMongoQueryService.kt │ │ ├── MongoCollections.kt │ │ ├── MongoProjectionConverter.kt │ │ ├── MongoSortConverter.kt │ │ ├── event │ │ ├── EventStreamConditionConverter.kt │ │ ├── MongoEventStreamQueryService.kt │ │ └── MongoEventStreamQueryServiceFactory.kt │ │ └── snapshot │ │ ├── MongoSnapshotQueryService.kt │ │ ├── MongoSnapshotQueryServiceFactory.kt │ │ └── SnapshotConditionConverter.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── mongo │ ├── DocumentsKtTest.kt │ ├── EventStreamSchemaInitializerTest.kt │ ├── MongoCommandDispatcherTest.kt │ ├── MongoEventStoreTest.kt │ ├── MongoSnapshotRepositoryTest.kt │ ├── SchemaInitializerSpec.kt │ ├── SnapshotSchemaInitializerTest.kt │ ├── prepare │ ├── MongoPrepareKeySpec.kt │ ├── ObjectMongoPrepareKeyTest.kt │ └── StringMongoPrepareKeyTest.kt │ └── query │ ├── SnapshotConditionConverterTest.kt │ ├── event │ ├── EventStreamConditionConverterTest.kt │ └── MongoEventStreamQueryServiceTest.kt │ └── snapshot │ └── MongoSnapshotQueryServiceTest.kt ├── wow-openapi ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── openapi │ │ │ ├── ApiResponseBuilder.kt │ │ │ ├── BatchComponent.kt │ │ │ ├── BatchResult.kt │ │ │ ├── BatchRouteSpec.kt │ │ │ ├── CommonComponent.kt │ │ │ ├── Https.kt │ │ │ ├── PathBuilder.kt │ │ │ ├── QueryComponent.kt │ │ │ ├── RequestBodyBuilder.kt │ │ │ ├── RouteIdSpec.kt │ │ │ ├── RouteSpec.kt │ │ │ ├── RouteSpecFactory.kt │ │ │ ├── RouterSpecs.kt │ │ │ ├── Tags.kt │ │ │ ├── aggregate │ │ │ ├── AggregateRouteSpec.kt │ │ │ ├── AggregateRouteSpecFactory.kt │ │ │ ├── AggregateRouteSpecFactoryProvider.kt │ │ │ ├── TenantOwnerAggregateRouteSpec.kt │ │ │ ├── TenantOwnerRouteSummarySpec.kt │ │ │ ├── command │ │ │ │ ├── CommandComponent.kt │ │ │ │ ├── CommandFacadeRouteSpec.kt │ │ │ │ └── CommandRouteSpec.kt │ │ │ ├── event │ │ │ │ ├── CountEventStreamRouteSpec.kt │ │ │ │ ├── EventCompensateRouteSpec.kt │ │ │ │ ├── EventComponent.kt │ │ │ │ ├── ListQueryEventStreamRouteSpec.kt │ │ │ │ ├── LoadEventStreamRouteSpec.kt │ │ │ │ ├── PagedQueryEventStreamRouteSpec.kt │ │ │ │ └── state │ │ │ │ │ └── ResendStateEventRouteSpec.kt │ │ │ ├── snapshot │ │ │ │ ├── BatchRegenerateSnapshotRouteSpec.kt │ │ │ │ ├── CountSnapshotRouteSpec.kt │ │ │ │ ├── ListQuerySnapshotRouteSpec.kt │ │ │ │ ├── ListQuerySnapshotStateRouteSpec.kt │ │ │ │ ├── LoadSnapshotRouteSpec.kt │ │ │ │ ├── PagedQuerySnapshotRouteSpec.kt │ │ │ │ ├── PagedQuerySnapshotStateRouteSpec.kt │ │ │ │ ├── RegenerateSnapshotRouteSpec.kt │ │ │ │ ├── SingleSnapshotRouteSpec.kt │ │ │ │ └── SingleSnapshotStateRouteSpec.kt │ │ │ └── state │ │ │ │ ├── AggregateTracingRouteSpec.kt │ │ │ │ ├── LoadAggregateComponent.kt │ │ │ │ ├── LoadAggregateRouteSpec.kt │ │ │ │ ├── LoadTimeBasedAggregateRouteSpec.kt │ │ │ │ └── LoadVersionedAggregateRouteSpec.kt │ │ │ ├── context │ │ │ ├── CurrentOpenAPIComponentContext.kt │ │ │ ├── DefaultOpenAPIComponentContext.kt │ │ │ ├── OpenAPIComponentContext.kt │ │ │ └── OpenAPIComponentContextCapable.kt │ │ │ ├── converter │ │ │ ├── BoundedContextSchemaNameConverter.kt │ │ │ └── WowSchemaConverter.kt │ │ │ ├── global │ │ │ ├── CommandWaitRouteSpec.kt │ │ │ ├── GenerateGlobalIdRouteSpec.kt │ │ │ ├── GenerateScriptRouteSpec.kt │ │ │ ├── GetWowMetadataRouteSpec.kt │ │ │ ├── GlobalRouteSpecFactory.kt │ │ │ └── GlobalRouteSpecFactoryProvider.kt │ │ │ └── metadata │ │ │ ├── AggregateRouteMetadata.kt │ │ │ ├── AggregateRouteMetadataParser.kt │ │ │ ├── CommandRouteMetadata.kt │ │ │ └── CommandRouteMetadataParser.kt │ └── resources │ │ └── META-INF │ │ ├── services │ │ ├── io.swagger.v3.core.converter.ModelConverter │ │ ├── me.ahoo.wow.openapi.aggregate.AggregateRouteSpecFactory │ │ └── me.ahoo.wow.openapi.global.GlobalRouteSpecFactory │ │ └── wow-metadata.json │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── openapi │ ├── BatchResultTest.kt │ ├── RouterSpecsTest.kt │ ├── TagsTest.kt │ ├── converter │ ├── BoundedContextSchemaNameConverterTest.kt │ └── ModelConvertersTest.kt │ └── metadata │ ├── AggregateRouteMetadataParserTest.kt │ ├── AggregateRouteMetadataTest.kt │ ├── CommandRouteMetadataParserTest.kt │ ├── CommandRouteMetadataTest.kt │ └── VariableMetadataTest.kt ├── wow-opentelemetry ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── opentelemetry │ │ ├── AggregateIdAttributesExtractor.kt │ │ ├── ExchangeAttributesExtractor.kt │ │ ├── ExchangeTraceMono.kt │ │ ├── ExchangeTraceSubscriber.kt │ │ ├── MessageAttributesExtractor.kt │ │ ├── TraceFilter.kt │ │ ├── TraceFlux.kt │ │ ├── TraceMono.kt │ │ ├── TraceSubscriber.kt │ │ ├── Tracing.kt │ │ ├── WowInstrumenter.kt │ │ ├── aggregate │ │ ├── AggregateInstrumenter.kt │ │ └── TraceAggregateFilter.kt │ │ ├── eventprocessor │ │ ├── EventProcessorInstrumenter.kt │ │ └── TraceEventProcessorFilter.kt │ │ ├── eventsourcing │ │ ├── EventStoreInstrumenter.kt │ │ └── TracingEventStore.kt │ │ ├── messaging │ │ ├── CommandProducerInstrumenter.kt │ │ ├── EventProducerInstrumenter.kt │ │ ├── MessageExchangeTextMapGetter.kt │ │ ├── MessageTextMapSetter.kt │ │ ├── StateEventProducerInstrumenter.kt │ │ ├── TracingCommandBus.kt │ │ ├── TracingEventBus.kt │ │ ├── TracingMessageBus.kt │ │ └── TracingStateEventBus.kt │ │ ├── projection │ │ ├── ProjectionInstrumenter.kt │ │ └── TraceProjectionFilter.kt │ │ ├── saga │ │ ├── StatelessSagaInstrumenter.kt │ │ └── TraceStatelessSagaFilter.kt │ │ └── snapshot │ │ ├── SnapshotInstrumenter.kt │ │ ├── SnapshotRepositoryInstrumenter.kt │ │ ├── TraceSnapshotFilter.kt │ │ └── TracingSnapshotRepository.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── opentelemetry │ ├── ExchangeTraceMonoTest.kt │ ├── eventsourcing │ └── TracingEventStoreTest.kt │ ├── messaging │ ├── MessageTextMapSetterTest.kt │ ├── TracingLocalCommandBusTest.kt │ ├── TracingLocalEventBusTest.kt │ └── TracingLocalStateEventBusTest.kt │ └── snapshot │ └── TracingSnapshotRepositoryTest.kt ├── wow-query ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── query │ │ ├── QueryService.kt │ │ ├── converter │ │ ├── AbstractConditionConverter.kt │ │ ├── ConditionConverter.kt │ │ ├── DeleteConditionGuard.kt │ │ ├── ProjectionConverter.kt │ │ └── SortConverter.kt │ │ ├── dsl │ │ ├── BetweenStart.kt │ │ ├── ConditionDsl.kt │ │ ├── Dsl.kt │ │ ├── ListQueryDsl.kt │ │ ├── NestedFieldDsl.kt │ │ ├── PagedQueryDsl.kt │ │ ├── PaginationDsl.kt │ │ ├── ProjectionDsl.kt │ │ ├── QueryableDsl.kt │ │ ├── SingleQueryDsl.kt │ │ └── SortDsl.kt │ │ ├── event │ │ ├── EventStreamQueryService.kt │ │ ├── EventStreamQueryServiceFactory.kt │ │ ├── QueryDsl.kt │ │ └── filter │ │ │ ├── EventStreamQueryFilter.kt │ │ │ ├── EventStreamQueryHandler.kt │ │ │ └── MaskingEventStreamQueryFilter.kt │ │ ├── filter │ │ ├── Contexts.kt │ │ ├── MaskingDynamicDocumentQueryFilter.kt │ │ ├── QueryContext.kt │ │ ├── QueryFilter.kt │ │ ├── QueryHandler.kt │ │ └── QueryType.kt │ │ ├── mask │ │ ├── AggregateDataMasker.kt │ │ ├── DataMasker.kt │ │ ├── DataMaskerRegistry.kt │ │ └── DataMasking.kt │ │ └── snapshot │ │ ├── QueryDsl.kt │ │ ├── SnapshotQueryService.kt │ │ ├── SnapshotQueryServiceFactory.kt │ │ ├── SnapshotStates.kt │ │ └── filter │ │ ├── MaskingSnapshotQueryFilter.kt │ │ ├── SnapshotQueryFilter.kt │ │ └── SnapshotQueryHandler.kt │ └── test │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── query │ │ ├── context │ │ └── ContextsTest.kt │ │ ├── converter │ │ └── DeleteConditionGuardTest.kt │ │ ├── dsl │ │ ├── ConditionDslTest.kt │ │ ├── ListQueryDslTest.kt │ │ ├── PagedQueryDslTest.kt │ │ ├── PaginationDslTest.kt │ │ ├── ProjectionDslTest.kt │ │ ├── SingleQueryDslTest.kt │ │ └── SortDslTest.kt │ │ ├── event │ │ ├── NoOpSnapshotQueryServiceFactoryTest.kt │ │ └── filter │ │ │ ├── DefaultEventStreamQueryHandlerTest.kt │ │ │ └── MaskingEventStreamQueryFilterTest.kt │ │ ├── mask │ │ ├── DataMaskingKtTest.kt │ │ ├── DefaultAggregateDataMaskerTest.kt │ │ └── StateDataMaskerRegistryTest.kt │ │ └── snapshot │ │ ├── NoOpSnapshotQueryServiceTest.kt │ │ ├── SnapshotStatesKtTest.kt │ │ └── filter │ │ ├── CountSnapshotQueryContextTest.kt │ │ ├── DefaultSnapshotQueryHandlerTest.kt │ │ └── MaskingSnapshotQueryFilterTest.kt │ └── resources │ ├── and.query.json │ └── empty.pagination.json ├── wow-r2dbc ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── r2dbc │ │ ├── Database.kt │ │ ├── EventStreamSchema.kt │ │ ├── R2dbcEventStore.kt │ │ ├── R2dbcSnapshotRepository.kt │ │ └── SnapshotSchema.kt │ └── test │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── r2dbc │ │ ├── ConnectionFactoryProviders.kt │ │ ├── MariadbLauncher.kt │ │ ├── R2DbcCommandDispatcherTest.kt │ │ ├── R2dbcEventStoreTest.kt │ │ ├── R2dbcSnapshotRepositoryTest.kt │ │ ├── ShardingDatabaseTest.kt │ │ ├── ShardingEventStreamSchemaTest.kt │ │ ├── ShardingSnapshotSchemaTest.kt │ │ ├── SimpleEventStreamSchemaTest.kt │ │ └── SimpleSnapshotSchemaTest.kt │ └── resources │ ├── init-schema-mysql.sql │ └── logback.xml ├── wow-redis ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── redis │ │ │ ├── bus │ │ │ ├── AbstractRedisMessageBus.kt │ │ │ ├── AggregateTopicConverter.kt │ │ │ ├── RedisCommandBus.kt │ │ │ ├── RedisDomainEventBus.kt │ │ │ ├── RedisEventStreamExchange.kt │ │ │ ├── RedisServerCommandExchange.kt │ │ │ ├── RedisStateEventBus.kt │ │ │ └── RedisStateEventExchange.kt │ │ │ ├── eventsourcing │ │ │ ├── AggregateKeyConverter.kt │ │ │ ├── EventStreamKeyConverter.kt │ │ │ ├── RedisEventStore.kt │ │ │ ├── RedisSnapshotRepository.kt │ │ │ ├── RedisWrappedKey.kt │ │ │ └── SnapshotKeyConverter.kt │ │ │ └── prepare │ │ │ ├── PrepareKeyConverter.kt │ │ │ ├── RedisPrepareKey.kt │ │ │ └── RedisPrepareKeyFactory.kt │ └── resources │ │ ├── event_steam_append.lua │ │ ├── prepare_prepare.lua │ │ ├── prepare_reprepare.lua │ │ ├── prepare_reprepare_with_old_value.lua │ │ ├── prepare_rollback.lua │ │ └── prepare_rollback_with_old_value.lua │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── redis │ ├── RedisCommandDispatcherTest.kt │ ├── RedisInitializer.kt │ ├── bus │ ├── DefaultCommandTopicConverterTest.kt │ ├── DefaultEventStreamTopicConverterTest.kt │ ├── DefaultStateEventTopicConverterTest.kt │ ├── RedisCommandBusTest.kt │ ├── RedisDomainEventBusTest.kt │ └── RedisStateEventBusTest.kt │ ├── eventsourcing │ ├── DefaultSnapshotKeyConverterTest.kt │ ├── EventStreamKeyConverterTest.kt │ ├── RedisEventStoreTest.kt │ ├── RedisSnapshotRepositoryTest.kt │ └── RedisWrappedKeyTest.kt │ └── prepare │ ├── ObjectRedisPrepareKeyTest.kt │ ├── RedisPrepareKeySpec.kt │ └── StringRedisPrepareKeyTest.kt ├── wow-schema ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── schema │ │ │ ├── DescriptionResolver.kt │ │ │ ├── IgnoreCommandRouteVariableCheck.kt │ │ │ ├── JavaTypeResolver.kt │ │ │ ├── JsonSchema.kt │ │ │ ├── JsonSchemaGenerator.kt │ │ │ ├── SummaryTitleResolver.kt │ │ │ ├── TypeFieldPaths.kt │ │ │ ├── Types.kt │ │ │ ├── WowModule.kt │ │ │ ├── WowOption.kt │ │ │ ├── WowSchemaLoader.kt │ │ │ ├── joda │ │ │ └── money │ │ │ │ ├── CurrencyUnitDefinitionProvider.kt │ │ │ │ ├── JodaMoneyModule.kt │ │ │ │ └── MoneyDefinitionProvider.kt │ │ │ ├── kotlin │ │ │ ├── KotlinCustomDefinitionProvider.kt │ │ │ ├── KotlinIgnoreCheck.kt │ │ │ ├── KotlinModule.kt │ │ │ ├── KotlinNullableCheck.kt │ │ │ ├── KotlinReadOnlyCheck.kt │ │ │ ├── KotlinRequiredCheck.kt │ │ │ └── KotlinWriteOnlyCheck.kt │ │ │ ├── naming │ │ │ ├── DefaultSchemaNamePrefixCapable.kt │ │ │ ├── SchemaNamingModule.kt │ │ │ └── WowSchemaNamingStrategy.kt │ │ │ ├── openapi │ │ │ ├── InlineSchemaCapable.kt │ │ │ ├── OpenAPISchemaBuilder.kt │ │ │ └── SchemaMerger.kt │ │ │ └── typed │ │ │ ├── AbstractStateAggregate.kt │ │ │ ├── AggregateIdDefinitionProvider.kt │ │ │ ├── AggregatedDomainEventStream.kt │ │ │ ├── AggregatedDomainEventStreamDefinitionProvider.kt │ │ │ ├── AggregatedFields.kt │ │ │ ├── AggregatedFieldsDefinitionProvider.kt │ │ │ ├── DomainEventStreamDefinitionProvider.kt │ │ │ ├── MessageDefinitionProvider.kt │ │ │ ├── TypedCustomDefinitionProvider.kt │ │ │ └── query │ │ │ ├── AggregatedCondition.kt │ │ │ ├── AggregatedConditionCapableDefinitionProvider.kt │ │ │ ├── AggregatedListQuery.kt │ │ │ ├── AggregatedPagedQuery.kt │ │ │ └── AggregatedSingleQuery.kt │ └── resources │ │ └── META-INF │ │ └── wow-schema │ │ ├── AggregateId.json │ │ ├── AggregatedDomainEventStream.json │ │ ├── CommandMessage.json │ │ ├── CurrencyUnit.json │ │ ├── DomainEvent.json │ │ ├── DomainEventStream.json │ │ ├── DomainEventStreamBody.json │ │ ├── Money.json │ │ ├── Snapshot.json │ │ ├── StateAggregate.json │ │ └── StateEvent.json │ └── test │ ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── schema │ │ ├── AggregatedFieldPathsTest.kt │ │ ├── JavaTypeResolverTest.kt │ │ ├── JsonSchemaGeneratorTest.kt │ │ ├── JsonSchemaTest.kt │ │ ├── JsonSchemaValidatorTest.kt │ │ ├── TypesTest.kt │ │ ├── WowSchemaLoaderTest.kt │ │ ├── WowSchemaNamingStrategyTest.kt │ │ ├── openapi │ │ └── OpenAPISchemaBuilderTest.kt │ │ └── typed │ │ └── query │ │ └── AggregatedConditionTest.kt │ └── resources │ └── META-INF │ ├── wow-metadata.json │ └── wow-schema │ ├── CartAggregatedDomainEventStream.json │ ├── CreateOrderCommandMessage.json │ ├── EmptyAggregatedDomainEventStream.json │ ├── MockStateAggregate.json │ ├── MockStateAggregateSnapshot.json │ ├── MockStateAggregateStateEvent.json │ ├── OrderAggregatedCondition.json │ ├── OrderAggregatedFields.json │ ├── OrderAggregatedListQuery.json │ ├── OrderAggregatedPagedQuery.json │ ├── OrderAggregatedSingleQuery.json │ └── OrderCreatedDomainEvent.json ├── wow-spring-boot-starter ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── me │ │ │ └── ahoo │ │ │ └── wow │ │ │ └── spring │ │ │ └── boot │ │ │ └── starter │ │ │ ├── BusProperties.kt │ │ │ ├── ConditionalOnWowEnabled.kt │ │ │ ├── WowAutoConfiguration.kt │ │ │ ├── WowProperties.kt │ │ │ ├── command │ │ │ ├── CommandAutoConfiguration.kt │ │ │ ├── CommandGatewayAutoConfiguration.kt │ │ │ ├── CommandProperties.kt │ │ │ ├── ConditionalOnCommandLocalFirstEnabled.kt │ │ │ └── ServerCommandWaitEndpoint.kt │ │ │ ├── compensation │ │ │ ├── CompensationAutoConfiguration.kt │ │ │ ├── CompensationProperties.kt │ │ │ └── ConditionalOnCompensationEnabled.kt │ │ │ ├── elasticsearch │ │ │ ├── ElasticsearchEventSourcingAutoConfiguration.kt │ │ │ └── ElasticsearchProperties.kt │ │ │ ├── event │ │ │ ├── ConditionalOnEventLocalFirstEnabled.kt │ │ │ ├── EventAutoConfiguration.kt │ │ │ ├── EventDispatcherAutoConfiguration.kt │ │ │ └── EventProperties.kt │ │ │ ├── eventsourcing │ │ │ ├── EventSourcingAutoConfiguration.kt │ │ │ ├── EventSourcingProperties.kt │ │ │ ├── StorageType.kt │ │ │ ├── snapshot │ │ │ │ ├── ConditionalOnSnapshotEnabled.kt │ │ │ │ ├── SnapshotAutoConfiguration.kt │ │ │ │ └── SnapshotProperties.kt │ │ │ ├── state │ │ │ │ ├── ConditionalOnStateEventLocalFirstEnabled.kt │ │ │ │ ├── StateAutoConfiguration.kt │ │ │ │ └── StateProperties.kt │ │ │ └── store │ │ │ │ ├── EventStoreAutoConfiguration.kt │ │ │ │ └── EventStoreProperties.kt │ │ │ ├── kafka │ │ │ ├── ConditionalOnKafkaEnabled.kt │ │ │ ├── KafkaAutoConfiguration.kt │ │ │ └── KafkaProperties.kt │ │ │ ├── metrics │ │ │ ├── ConditionalOnMetricsEnabled.kt │ │ │ ├── MetricsAutoConfiguration.kt │ │ │ └── MetricsBeanPostProcessor.kt │ │ │ ├── mock │ │ │ ├── MockEventStoreAutoConfiguration.kt │ │ │ └── MockSnapshotAutoConfiguration.kt │ │ │ ├── modeling │ │ │ └── AggregateAutoConfiguration.kt │ │ │ ├── mongo │ │ │ ├── ConditionalOnMongoEnabled.kt │ │ │ ├── MongoEventSourcingAutoConfiguration.kt │ │ │ └── MongoProperties.kt │ │ │ ├── openapi │ │ │ ├── ConditionalOnOpenAPIEnabled.kt │ │ │ ├── OpenAPIAutoConfiguration.kt │ │ │ ├── OpenAPIProperties.kt │ │ │ └── WowOpenApiCustomizer.kt │ │ │ ├── opentelemetry │ │ │ ├── ConditionalOnOpenTelemetryEnabled.kt │ │ │ ├── TracingBeanPostProcessor.kt │ │ │ └── WowOpenTelemetryAutoConfiguration.kt │ │ │ ├── prepare │ │ │ ├── ConditionalOnPrepareEnabled.kt │ │ │ ├── PrepareAutoConfiguration.kt │ │ │ └── PrepareProperties.kt │ │ │ ├── projection │ │ │ └── ProjectionDispatcherAutoConfiguration.kt │ │ │ ├── query │ │ │ └── QueryAutoConfiguration.kt │ │ │ ├── r2dbc │ │ │ ├── ConditionalOnR2dbcEnabled.kt │ │ │ ├── DataSourceProperties.kt │ │ │ ├── R2dbcAutoConfiguration.kt │ │ │ ├── R2dbcProperties.kt │ │ │ ├── ShardingDataSourcingAutoConfiguration.kt │ │ │ ├── ShardingProperties.kt │ │ │ ├── eventstore │ │ │ │ └── R2dbcEventStoreAutoConfiguration.kt │ │ │ └── snapshot │ │ │ │ └── R2dbcSnapshotAutoConfiguration.kt │ │ │ ├── redis │ │ │ ├── ConditionalOnRedisEnabled.kt │ │ │ ├── RedisEventSourcingAutoConfiguration.kt │ │ │ ├── RedisMessageBusAutoConfiguration.kt │ │ │ └── RedisProperties.kt │ │ │ ├── saga │ │ │ └── StatelessSagaAutoConfiguration.kt │ │ │ ├── serialization │ │ │ └── SerializationAutoConfiguration.kt │ │ │ └── webflux │ │ │ ├── ConditionalOnWebfluxEnabled.kt │ │ │ ├── ConditionalOnWebfluxGlobalErrorEnabled.kt │ │ │ ├── WebFluxAutoConfiguration.kt │ │ │ ├── WebFluxProperties.kt │ │ │ └── WowWebClientAutoConfiguration.kt │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── spring │ └── boot │ └── starter │ ├── ApplicationContextRunnerKit.kt │ ├── WowAutoConfigurationTest.kt │ ├── command │ ├── CommandAutoConfigurationTest.kt │ ├── CommandGatewayAutoConfigurationTest.kt │ └── ServerCommandWaitEndpointTest.kt │ ├── compensation │ └── CompensationAutoConfigurationTest.kt │ ├── elasticsearch │ └── ElasticsearchEventSourcingAutoConfigurationTest.kt │ ├── event │ ├── EventAutoConfigurationTest.kt │ └── EventDispatcherAutoConfigurationTest.kt │ ├── eventsourcing │ ├── EventSourcingAutoConfigurationTest.kt │ ├── snapshot │ │ └── SnapshotAutoConfigurationTest.kt │ ├── state │ │ └── StateAutoConfigurationTest.kt │ └── store │ │ └── EventStoreAutoConfigurationTest.kt │ ├── kafka │ └── KafkaAutoConfigurationTest.kt │ ├── metrics │ └── MetricsAutoConfigurationTest.kt │ ├── mock │ ├── MockEventStoreAutoConfigurationTest.kt │ └── MockSnapshotAutoConfigurationTest.kt │ ├── modeling │ └── AggregateAutoConfigurationTest.kt │ ├── mongo │ └── MongoEventSourcingAutoConfigurationTest.kt │ ├── openapi │ └── OpenAPIAutoConfigurationTest.kt │ ├── opentelemetry │ └── WowOpenTelemetryAutoConfigurationTest.kt │ ├── prepare │ └── PrepareAutoConfigurationTest.kt │ ├── projection │ └── ProjectionDispatcherAutoConfigurationTest.kt │ ├── query │ └── QueryAutoConfigurationTest.kt │ ├── r2dbc │ ├── R2dbcAutoConfigurationTest.kt │ └── ShardingDataSourcingAutoConfigurationTest.kt │ ├── redis │ ├── RedisEventSourcingAutoConfigurationTest.kt │ └── RedisMessageBusAutoConfigurationTest.kt │ ├── saga │ └── StatelessSagaAutoConfigurationTest.kt │ ├── serialization │ └── SerializationAutoConfigurationTest.kt │ └── webflux │ ├── WebFluxAutoConfigurationTest.kt │ └── WowWebClientAutoConfigurationTest.kt ├── wow-spring ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── me │ │ └── ahoo │ │ └── wow │ │ └── spring │ │ ├── AutoRegistrar.kt │ │ ├── MessageDispatcherLauncher.kt │ │ ├── SpringServiceProvider.kt │ │ ├── command │ │ ├── CommandDispatcherLauncher.kt │ │ └── SnapshotDispatcherLauncher.kt │ │ ├── event │ │ ├── DomainEventDispatcherLauncher.kt │ │ └── EventProcessorAutoRegistrar.kt │ │ ├── projection │ │ ├── ProjectionDispatcherLauncher.kt │ │ └── ProjectionProcessorAutoRegistrar.kt │ │ ├── query │ │ ├── EventStreamQueryServiceRegistrar.kt │ │ ├── QueryServiceRegistrar.kt │ │ └── SnapshotQueryServiceRegistrar.kt │ │ ├── saga │ │ ├── StatelessSagaDispatcherLauncher.kt │ │ └── StatelessSagaProcessorAutoRegistrar.kt │ │ └── stereotype │ │ ├── EventProcessor.kt │ │ ├── ProjectionProcessor.kt │ │ └── StatelessSaga.kt │ └── test │ └── kotlin │ └── me │ └── ahoo │ └── wow │ └── spring │ ├── MessageDispatcherLauncherTest.kt │ └── SpringServiceProviderTest.kt └── wow-webflux ├── build.gradle.kts └── src ├── main ├── kotlin │ └── me │ │ └── ahoo │ │ └── wow │ │ └── webflux │ │ ├── exception │ │ ├── BatchTaskException.kt │ │ ├── ErrorHttpStatusMapping.kt │ │ ├── GlobalExceptionHandler.kt │ │ ├── HandlerMethodValidationExceptionConverter.kt │ │ ├── NoResourceFoundExceptionConverter.kt │ │ ├── RequestExceptionHandler.kt │ │ └── ServerWebInputExceptionConverter.kt │ │ ├── route │ │ ├── BatchResults.kt │ │ ├── Responses.kt │ │ ├── RouteHandlerFunctionFactory.kt │ │ ├── RouteHandlerFunctionRegistrar.kt │ │ ├── RouterFunctionBuilder.kt │ │ ├── command │ │ │ ├── AggregateRequest.kt │ │ │ ├── CommandBodyExtractor.kt │ │ │ ├── CommandFacadeBodyExtractor.kt │ │ │ ├── CommandFacadeHandlerFunction.kt │ │ │ ├── CommandHandler.kt │ │ │ ├── CommandHandlerFunction.kt │ │ │ ├── CommandMessageParser.kt │ │ │ └── appender │ │ │ │ ├── CommandRequestExtendHeaderAppender.kt │ │ │ │ ├── CommandRequestHeaderAppender.kt │ │ │ │ ├── CommandRequestRemoteIpHeaderAppender.kt │ │ │ │ └── CommandRequestUserAgentHeaderAppender.kt │ │ ├── event │ │ │ ├── CountEventStreamHandlerFunction.kt │ │ │ ├── EventCompensateHandlerFunction.kt │ │ │ ├── ListQueryEventStreamHandlerFunction.kt │ │ │ ├── LoadEventStreamHandlerFunction.kt │ │ │ ├── PagedQueryEventStreamHandlerFunction.kt │ │ │ └── state │ │ │ │ ├── ResendStateEventFunction.kt │ │ │ │ └── ResendStateEventHandler.kt │ │ ├── global │ │ │ ├── GenerateBIScriptHandlerFunction.kt │ │ │ ├── GetWowMetadataHandlerFunction.kt │ │ │ └── GlobalIdHandlerFunction.kt │ │ ├── query │ │ │ ├── CountQueryHandlerFunction.kt │ │ │ ├── ListQueryHandlerFunction.kt │ │ │ ├── PagedQueryHandlerFunction.kt │ │ │ ├── RewriteRequestCondition.kt │ │ │ └── SingleQueryHandlerFunction.kt │ │ ├── snapshot │ │ │ ├── BatchRegenerateSnapshotHandlerFunction.kt │ │ │ ├── CountSnapshotHandlerFunction.kt │ │ │ ├── ListQuerySnapshotHandlerFunction.kt │ │ │ ├── ListQuerySnapshotStateHandlerFunction.kt │ │ │ ├── LoadSnapshotHandlerFunction.kt │ │ │ ├── PagedQuerySnapshotHandlerFunction.kt │ │ │ ├── PagedQuerySnapshotStateHandlerFunction.kt │ │ │ ├── RegenerateSnapshotHandler.kt │ │ │ ├── RegenerateSnapshotHandlerFunction.kt │ │ │ ├── SingleSnapshotHandlerFunction.kt │ │ │ └── SingleSnapshotStateHandlerFunction.kt │ │ └── state │ │ │ ├── AbstractLoadAggregateHandlerFunction.kt │ │ │ ├── AggregateTracingHandlerFunction.kt │ │ │ ├── LoadAggregateHandlerFunction.kt │ │ │ ├── LoadTimeBasedAggregateHandlerFunction.kt │ │ │ ├── LoadVersionedAggregateHandlerFunction.kt │ │ │ └── OwnerAggregatePrecondition.kt │ │ └── wait │ │ ├── CommandWaitHandlerFunction.kt │ │ └── WebClientCommandWaitNotifier.kt └── resources │ └── META-INF │ └── services │ └── me.ahoo.wow.exception.ErrorConverterFactory └── test └── kotlin └── me └── ahoo └── wow └── webflux ├── exception ├── DefaultExceptionHandlerTest.kt ├── DefaultRequestExceptionHandlerTest.kt ├── ErrorHttpStatusMappingTest.kt ├── GlobalExceptionHandlerTest.kt ├── HandlerMethodValidationExceptionConverterTest.kt ├── NoResourceFoundExceptionConverterTest.kt └── ServerWebInputExceptionConverterTest.kt ├── handler └── CommandHandlerTest.kt ├── route ├── BatchResultsKtTest.kt ├── ResponsesKtTest.kt ├── bi │ └── GenerateBIScriptHandlerFunctionTest.kt ├── command │ ├── AggregateRequestTest.kt │ ├── CommandBodyExtractorTest.kt │ ├── CommandFacadeBodyExtractorTest.kt │ ├── CommandFacadeHandlerFunctionTest.kt │ ├── CommandHandlerFunctionTest.kt │ ├── DefaultCommandMessageParserTest.kt │ └── appender │ │ ├── CommandRequestExtendHeaderAppenderTest.kt │ │ ├── CommandRequestRemoteIpHeaderAppenderTest.kt │ │ └── CommandRequestUserAgentHeaderAppenderTest.kt ├── compensation │ └── EventCompensateHandlerFunctionTest.kt ├── event │ ├── ListQueryEventStreamHandlerFunctionTest.kt │ ├── LoadEventStreamHandlerFunctionTest.kt │ ├── MockQueryHandler.kt │ └── state │ │ └── ResendStateEventHandlerTest.kt ├── id │ └── GlobalIdHandlerFunctionTest.kt ├── metadata │ └── GetWowMetadataHandlerFunctionTest.kt ├── snapshot │ ├── BatchRegenerateSnapshotHandlerFunctionTest.kt │ ├── CountSnapshotHandlerFunctionTest.kt │ ├── ListQuerySnapshotHandlerFunctionTest.kt │ ├── ListQuerySnapshotStateHandlerFunctionTest.kt │ ├── LoadSnapshotHandlerFunctionTest.kt │ ├── MockQueryHandler.kt │ ├── PagedQuerySnapshotHandlerFunctionFactoryTest.kt │ ├── PagedQuerySnapshotStateHandlerFunctionFactoryTest.kt │ ├── RegenerateSnapshotHandlerFunctionTest.kt │ ├── SingleSnapshotHandlerFunctionTest.kt │ └── SingleSnapshotStateHandlerFunctionTest.kt └── state │ ├── AggregateTracingHandlerFunctionTest.kt │ ├── LoadAggregateHandlerFunctionTest.kt │ ├── LoadTimeBasedAggregateHandlerFunctionTest.kt │ ├── LoadVersionedAggregateHandlerFunctionTest.kt │ ├── OwnerAggregatePreconditionTest.kt │ └── ResendStateEventHandlerFunctionTest.kt └── wait ├── CommandWaitHandlerFunctionTest.kt └── WebClientCommandWaitNotifierTest.kt /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | [*.{kt,kts}] 7 | ij_kotlin_allow_trailing_comma = false 8 | ij_kotlin_packages_to_use_import_on_demand = java.util.*,org.hamcrest.Matchers.*,org.hamcrest.MatcherAssert.*,org.junit.jupiter.api.Assertions.* -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Fixes #ISSUSE_ID. 2 | 3 | Changes proposed in this pull request: 4 | - 5 | - 6 | - 7 | -------------------------------------------------------------------------------- /.github/workflows/gitee-sync.yml: -------------------------------------------------------------------------------- 1 | name: Sync to Gitee 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | push: 6 | branches: 7 | - main 8 | - gh-pages 9 | # - gh-pages-with-site-base 10 | workflow_dispatch: 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Sync to Gitee 16 | uses: wearerequired/git-mirror-action@master 17 | env: 18 | SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} 19 | with: 20 | source-repo: "git@github.com:Ahoo-Wang/Wow.git" 21 | destination-repo: "git@gitee.com:AhooWang/Wow.git" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /build/ 3 | 4 | # Ignore Gradle GUI config 5 | gradle-app.setting 6 | 7 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 8 | !gradle-wrapper.jar 9 | 10 | # Cache of project 11 | .gradletasknamecache 12 | 13 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 14 | # gradle/wrapper/gradle-wrapper.properties 15 | 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | # Zeppelin ignored files 10 | /ZeppelinRemoteNotebooks/ 11 | # GitHub Copilot persisted chat sessions 12 | /copilot/chatSessions 13 | -------------------------------------------------------------------------------- /.idea/Wow.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10.3.2 5 | JavaOnly 6 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 11 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/ahoo_wang.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mongo 6 | true 7 | com.dbschema.MongoJdbcDriver 8 | mongodb://localhost:27017 9 | $ProjectFileDir$ 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/detekt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 17 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/modules/Wow.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/Wow.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-api/Wow.wow-compensation-api.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-api/Wow.wow-compensation-api.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-api/Wow.wow-compensation-api.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-core/Wow.wow-compensation-core.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-domain/Wow.wow-compensation-domain.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-server/Wow.wow-compensation-server.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/compensation/wow-compensation-server/Wow.wow-compensation-server.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-api/Wow.example-api.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-api/Wow.example-api.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-api/Wow.example-api.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-domain/Wow.example-domain.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-domain/Wow.example-domain.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-domain/Wow.example-domain.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-server/Wow.example-server.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/example-server/Wow.example-server.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/transfer/example-transfer-api/Wow.example-transfer-api.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/modules/example/transfer/example-transfer-api/Wow.example-transfer-api.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/transfer/example-transfer-domain/Wow.example-transfer-domain.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/transfer/example-transfer-domain/Wow.example-transfer-domain.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/example/transfer/example-transfer-server/Wow.example-transfer-server.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-mock/Wow.wow-mock.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-tck/Wow.wow-tck.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-tck/Wow.wow-tck.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-tck/Wow.wow-tck.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-tck/me.ahoo.wow.Wow.wow-tck.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-tck/me.ahoo.wow.Wow.wow-tck.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-test/Wow.wow-test.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/test/wow-test/me.ahoo.wow.Wow.wow-test.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-api/Wow.wow-api.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-api/Wow.wow-api.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-api/Wow.wow-api.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-apiclient/Wow.wow-apiclient.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-apiclient/Wow.wow-apiclient.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/modules/wow-bi/Wow.wow-bi.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-bom/Wow.wow-bom.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-cocache/Wow.wow-cocache.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/modules/wow-cocache/Wow.wow-cocache.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-compiler/Wow.wow-compiler.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-compiler/Wow.wow-compiler.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-core/Wow.wow-core.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-core/Wow.wow-core.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-core/Wow.wow-core.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-dependencies/Wow.wow-dependencies.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-elasticsearch/Wow.wow-elasticsearch.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-elasticsearch/Wow.wow-elasticsearch.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-elasticsearch/Wow.wow-elasticsearch.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-it/Wow.wow-it.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-kafka/Wow.wow-kafka.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-kafka/Wow.wow-kafka.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-models/Wow.wow-models.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-mongo/Wow.wow-mongo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-mongo/Wow.wow-mongo.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-mongo/Wow.wow-mongo.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-openapi/Wow.wow-openapi.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-opentelemetry/Wow.wow-opentelemetry.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-opentelemetry/Wow.wow-opentelemetry.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-opentelemetry/Wow.wow-opentelemetry.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-query/Wow.wow-query.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-query/Wow.wow-query.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-query/Wow.wow-query.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-r2dbc/Wow.wow-r2dbc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-redis/Wow.wow-redis.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-schema/Wow.wow-schema.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring-boot-starter/Wow.wow-spring-boot-starter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring-boot-starter/Wow.wow-spring-boot-starter.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring-boot-starter/Wow.wow-spring-boot-starter.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring/Wow.wow-spring.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring/Wow.wow-spring.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-spring/Wow.wow-spring.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-webflux/Wow.wow-webflux.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-webflux/Wow.wow-webflux.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules/wow-webflux/Wow.wow-webflux.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/sqldialects.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: 60..100 3 | round: down 4 | precision: 2 5 | status: 6 | patch: 7 | default: 8 | target: 60% 9 | threshold: 1% 10 | project: 11 | default: 12 | target: 80% 13 | threshold: 1% 14 | ignore: 15 | - "document/.*" 16 | - "test/wow-it/.*" 17 | - "test/wow-tck/.*" 18 | - "test/wow-test/.*" 19 | - "wow-api/.*" 20 | - "wow-apiclient/.*" 21 | - "example/example-api/.*" 22 | - "example/transfer/example-transfer-api/.*" -------------------------------------------------------------------------------- /compensation/wow-compensation-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(platform(project(":wow-dependencies"))) 6 | api("io.swagger.core.v3:swagger-core-jakarta") 7 | implementation(project(":wow-api")) 8 | implementation("com.fasterxml.jackson.core:jackson-annotations") 9 | api("jakarta.validation:jakarta.validation-api") 10 | api("io.projectreactor:reactor-core") 11 | ksp(project(":wow-compiler")) 12 | } 13 | -------------------------------------------------------------------------------- /compensation/wow-compensation-core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(platform(project(":wow-dependencies"))) 3 | implementation(project(":wow-compensation-api")) 4 | implementation(project(":wow-core")) 5 | testImplementation(project(":wow-compensation-domain")) 6 | testImplementation(project(":wow-test")) 7 | testImplementation("io.projectreactor:reactor-test") 8 | } 9 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/api/ApplyRetrySpec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | export interface ApplyRetrySpec { 15 | maxRetries: number 16 | minBackoff: number 17 | executionTimeout: number 18 | } 19 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/api/ChangeFunction.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | import {FunctionInfo} from "./ExecutionFailedState"; 15 | 16 | export interface ChangeFunction extends FunctionInfo { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/api/PagedList.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | export interface PagedList { 15 | total: number; 16 | list: T[]; 17 | } 18 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | .logo { 2 | width: 48px; 3 | height: 48px; 4 | margin: 0 24px 0 0; 5 | float: left; 6 | } 7 | 8 | .logo img { 9 | display: inline-block; 10 | height: 48px; 11 | width: 48px; 12 | vertical-align: middle; 13 | } 14 | 15 | [nz-menu] { 16 | line-height: 64px; 17 | } 18 | 19 | nz-header { 20 | width: 100%; 21 | } 22 | 23 | nz-content { 24 | padding: 0 10px; 25 | } 26 | 27 | nz-footer { 28 | text-align: center; 29 | } 30 | 31 | .inner-content { 32 | background: #fff; 33 | padding: 10px; 34 | min-height: 600px; 35 | } 36 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {CommonModule, NgOptimizedImage} from '@angular/common'; 3 | import {RouterLink, RouterOutlet} from '@angular/router'; 4 | import {NzIconModule} from 'ng-zorro-antd/icon'; 5 | import {NzLayoutModule} from 'ng-zorro-antd/layout'; 6 | import {NzMenuModule} from 'ng-zorro-antd/menu'; 7 | 8 | @Component({ 9 | selector: 'app-root', 10 | imports: [CommonModule, RouterOutlet, NzIconModule, NzLayoutModule, NzMenuModule, RouterLink, NgOptimizedImage], 11 | templateUrl: './app.component.html', 12 | styleUrls: ['./app.component.scss'] 13 | }) 14 | export class AppComponent { 15 | title: string = "wow-compensation-dashboard" 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/apply-retry-spec/apply-retry-spec.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/apply-retry-spec/apply-retry-spec.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/apply-retry-spec/apply-retry-spec.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ApplyRetrySpecComponent } from './apply-retry-spec.component'; 4 | 5 | describe('ApplyRetrySpecComponent', () => { 6 | let component: ApplyRetrySpecComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ApplyRetrySpecComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ApplyRetrySpecComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/error/error.component.scss: -------------------------------------------------------------------------------- 1 | .editor { 2 | height: 800px; 3 | } 4 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/error/error.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ErrorComponent } from './error.component'; 4 | 5 | describe('ErrorComponent', () => { 6 | let component: ErrorComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ErrorComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ErrorComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/error/error.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | 3 | import {NzCodeEditorModule} from 'ng-zorro-antd/code-editor'; 4 | 5 | import {ExecutionFailedState} from "../api/ExecutionFailedState"; 6 | import {NzDescriptionsComponent, NzDescriptionsItemComponent} from "ng-zorro-antd/descriptions"; 7 | import {FormsModule} from "@angular/forms"; 8 | import {NzTypographyComponent} from "ng-zorro-antd/typography"; 9 | 10 | @Component({ 11 | selector: 'app-error', 12 | imports: [NzCodeEditorModule, NzDescriptionsComponent, NzDescriptionsItemComponent, FormsModule, NzTypographyComponent], 13 | templateUrl: './error.component.html', 14 | styleUrl: './error.component.scss' 15 | }) 16 | export class ErrorComponent { 17 | @Input({required: true}) state!: ExecutionFailedState 18 | } 19 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/executing/executing.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/executing/executing.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/executing/executing.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/executing/executing.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ExecutingComponent } from './executing.component'; 4 | 5 | describe('ExecutingComponent', () => { 6 | let component: ExecutingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ExecutingComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ExecutingComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/executing/executing.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {FailedListComponent} from "../failed-list/failed-list.component"; 3 | import {FindCategory} from "../api/CompensationClient"; 4 | 5 | @Component({ 6 | selector: 'app-executing', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './executing.component.html', 11 | styleUrl: './executing.component.scss' 12 | }) 13 | export class ExecutingComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/failed-history/failed-history.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/failed-history/failed-history.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/failed-history/failed-history.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FailedHistoryComponent } from './failed-history.component'; 4 | 5 | describe('FailedHistoryComponent', () => { 6 | let component: FailedHistoryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [FailedHistoryComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(FailedHistoryComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/failed-list/failed-list.component.scss: -------------------------------------------------------------------------------- 1 | .search-form { 2 | padding: 24px; 3 | background: #fbfbfb; 4 | border: 1px solid #f0f0f0; 5 | margin-bottom: 10px; 6 | } 7 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/failed-list/failed-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FailedListComponent } from './failed-list.component'; 4 | 5 | describe('FailedListComponent', () => { 6 | let component: FailedListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [FailedListComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(FailedListComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/icons-provider.ts: -------------------------------------------------------------------------------- 1 | import { EnvironmentProviders, importProvidersFrom } from '@angular/core'; 2 | import { 3 | MenuFoldOutline, 4 | MenuUnfoldOutline, 5 | FormOutline, 6 | DashboardOutline 7 | } from '@ant-design/icons-angular/icons'; 8 | import { NzIconModule } from 'ng-zorro-antd/icon'; 9 | 10 | const icons = [MenuFoldOutline, MenuUnfoldOutline, DashboardOutline, FormOutline]; 11 | 12 | export function provideNzIcons(): EnvironmentProviders { 13 | return importProvidersFrom(NzIconModule.forRoot(icons)); 14 | } 15 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/next-retry/next-retry.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/next-retry/next-retry.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/next-retry/next-retry.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/next-retry/next-retry.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NextRetryComponent } from './next-retry.component'; 4 | 5 | describe('NextRetryComponent', () => { 6 | let component: NextRetryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [NextRetryComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(NextRetryComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/next-retry/next-retry.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {FindCategory} from "../api/CompensationClient"; 3 | import {FailedListComponent} from "../failed-list/failed-list.component"; 4 | 5 | @Component({ 6 | selector: 'app-next-retry', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './next-retry.component.html', 11 | styleUrl: './next-retry.component.scss' 12 | }) 13 | export class NextRetryComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/non-retryable/non-retryable.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/non-retryable/non-retryable.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/non-retryable/non-retryable.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/non-retryable/non-retryable.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NonRetryableComponent } from './non-retryable.component'; 4 | 5 | describe('NonRetryableComponent', () => { 6 | let component: NonRetryableComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [NonRetryableComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(NonRetryableComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/non-retryable/non-retryable.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {FindCategory} from "../api/CompensationClient"; 3 | import {FailedListComponent} from "../failed-list/failed-list.component"; 4 | 5 | @Component({ 6 | selector: 'app-non-retryable', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './non-retryable.component.html', 11 | styleUrl: './non-retryable.component.scss' 12 | }) 13 | export class NonRetryableComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/succeeded/succeeded.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/succeeded/succeeded.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/succeeded/succeeded.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/succeeded/succeeded.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SucceededComponent } from './succeeded.component'; 4 | 5 | describe('SucceededComponent', () => { 6 | let component: SucceededComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [SucceededComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(SucceededComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/succeeded/succeeded.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {FindCategory} from "../api/CompensationClient"; 3 | import {FailedListComponent} from "../failed-list/failed-list.component"; 4 | 5 | @Component({ 6 | selector: 'app-succeeded', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './succeeded.component.html', 11 | styleUrl: './succeeded.component.scss' 12 | }) 13 | export class SucceededComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/to-retry/to-retry.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/to-retry/to-retry.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/to-retry/to-retry.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/to-retry/to-retry.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ToRetryComponent } from './to-retry.component'; 4 | 5 | describe('ToRetryComponent', () => { 6 | let component: ToRetryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ToRetryComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ToRetryComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/to-retry/to-retry.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {FailedListComponent} from "../failed-list/failed-list.component"; 3 | import {FindCategory} from "../api/CompensationClient"; 4 | 5 | @Component({ 6 | selector: 'app-to-retry', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './to-retry.component.html', 11 | styleUrl: './to-retry.component.scss' 12 | }) 13 | export class ToRetryComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/unrecoverable/unrecoverable.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/unrecoverable/unrecoverable.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/app/unrecoverable/unrecoverable.component.scss -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/unrecoverable/unrecoverable.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UnrecoverableComponent } from './unrecoverable.component'; 4 | 5 | describe('UnrecoverableComponent', () => { 6 | let component: UnrecoverableComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [UnrecoverableComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(UnrecoverableComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/app/unrecoverable/unrecoverable.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {FailedListComponent} from "../failed-list/failed-list.component"; 3 | import {FindCategory} from "../api/CompensationClient"; 4 | 5 | @Component({ 6 | selector: 'app-unrecoverable', 7 | imports: [ 8 | FailedListComponent 9 | ], 10 | templateUrl: './unrecoverable.component.html', 11 | styleUrl: './unrecoverable.component.scss' 12 | }) 13 | export class UnrecoverableComponent { 14 | 15 | protected readonly FindCategory = FindCategory; 16 | } 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/assets/.gitkeep -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/environments/environment.development.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: false, 3 | host: 'http://compensation-service.dev.svc.cluster.local' 4 | }; 5 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | host: '' 4 | }; 5 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-dashboard/src/favicon.ico -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Wow Compensation Dashboard 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/src/theme.less: -------------------------------------------------------------------------------- 1 | 2 | // Custom Theming for NG-ZORRO 3 | // For more information: https://ng.ant.design/docs/customize-theme/en 4 | //@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; 5 | 6 | // Override less variables to here 7 | // View all variables: https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/style/themes/default.less 8 | 9 | // @primary-color: #1890ff; 10 | 11 | @import "../node_modules/ng-zorro-antd/ng-zorro-antd.compact.less"; 12 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /compensation/wow-compensation-dashboard/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /compensation/wow-compensation-domain/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(project(":wow-compensation-api")) 6 | api(project(":wow-spring")) 7 | ksp(project(":wow-compiler")) 8 | testImplementation(project(":wow-test")) 9 | testImplementation("io.projectreactor:reactor-test") 10 | } 11 | 12 | tasks.jacocoTestCoverageVerification { 13 | dependsOn(tasks.test, tasks.jacocoTestReport) 14 | violationRules { 15 | rule { 16 | limit { 17 | minimum = 0.8.toBigDecimal() 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compensation/wow-compensation-server/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG APP_NAME=wow-compensation-server 2 | ARG WORK_HOME=/opt/${APP_NAME} 3 | 4 | FROM dragonwell-registry.cn-hangzhou.cr.aliyuncs.com/dragonwell/dragonwell:21-ubuntu AS base 5 | 6 | FROM base as build 7 | ARG WORK_HOME 8 | ARG APP_NAME 9 | 10 | WORKDIR ${WORK_HOME} 11 | COPY build/install/${APP_NAME} . 12 | 13 | FROM base as run 14 | ARG WORK_HOME 15 | 16 | COPY --from=build ${WORK_HOME} ${WORK_HOME} 17 | 18 | WORKDIR ${WORK_HOME} 19 | EXPOSE 8080 20 | 21 | ENTRYPOINT ["bin/wow-compensation-server"] 22 | -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/dist/logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/compensation/wow-compensation-server/src/dist/logs/.gitignore -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ██ ██ 2 | ░██ ░██ 3 | ░██ █ ░██ ██████ ███ ██ 4 | ░██ ███ ░██ ██░░░░██░░██ █ ░██ :: Java :: (v${java.version}) 5 | ░██ ██░██░██░██ ░██ ░██ ███░██ :: Spring Boot :: (v${spring-boot.version}) 6 | ░████ ░░████░██ ░██ ░████░████ ------------------------------------------- 7 | ░██░ ░░░██░░██████ ███░ ░░░██ :: Wow :: (v${application.version}) 8 | ░░ ░░ ░░░░░░ ░░░ ░░░ 9 | -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/jte/compensation_prepared.kte: -------------------------------------------------------------------------------- 1 | @import java.time.LocalDateTime 2 | @import java.time.Instant 3 | @import java.time.ZoneId 4 | @import java.time.format.DateTimeFormatter 5 | 6 | @import me.ahoo.wow.api.event.DomainEvent 7 | @import me.ahoo.wow.modeling.state.ReadOnlyStateAggregate 8 | @import me.ahoo.wow.compensation.api.IExecutionFailedState 9 | @import me.ahoo.wow.compensation.api.CompensationPrepared 10 | 11 | @param host: String 12 | @param event: DomainEvent 13 | @param state: ReadOnlyStateAggregate 14 | 15 | @template.layout( 16 | title = "Compensation Prepared", 17 | host= host, 18 | state = state, 19 | ) -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/jte/execution_failed_applied.kte: -------------------------------------------------------------------------------- 1 | @import java.time.LocalDateTime 2 | @import java.time.Instant 3 | @import java.time.ZoneId 4 | @import java.time.format.DateTimeFormatter 5 | 6 | @import me.ahoo.wow.api.event.DomainEvent 7 | @import me.ahoo.wow.modeling.state.ReadOnlyStateAggregate 8 | @import me.ahoo.wow.compensation.api.IExecutionFailedState 9 | @import me.ahoo.wow.compensation.api.ExecutionFailedApplied 10 | 11 | @param host: String 12 | @param event: DomainEvent 13 | @param state: ReadOnlyStateAggregate 14 | 15 | @template.layout( 16 | title = "Execution Failed", 17 | host= host, 18 | state = state, 19 | ) 20 | ## Error 21 | - Code: ${"`"}${event.body.error.errorCode}${"`"} 22 | - Message: ${event.body.error.errorMsg} -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/jte/execution_failed_created.kte: -------------------------------------------------------------------------------- 1 | @import java.time.LocalDateTime 2 | @import java.time.Instant 3 | @import java.time.ZoneId 4 | @import java.time.format.DateTimeFormatter 5 | 6 | @import me.ahoo.wow.api.event.DomainEvent 7 | @import me.ahoo.wow.modeling.state.ReadOnlyStateAggregate 8 | @import me.ahoo.wow.compensation.api.IExecutionFailedState 9 | @import me.ahoo.wow.compensation.api.ExecutionFailedCreated 10 | 11 | @param host: String 12 | @param event: DomainEvent 13 | @param state: ReadOnlyStateAggregate 14 | 15 | @template.layout( 16 | title = "Execution Failed", 17 | host= host, 18 | state = state, 19 | ) 20 | ## Error 21 | - Code: ${"`"}${event.body.error.errorCode}${"`"} 22 | - Message: ${event.body.error.errorMsg} -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/jte/execution_success_applied.kte: -------------------------------------------------------------------------------- 1 | @import java.time.LocalDateTime 2 | @import java.time.Instant 3 | @import java.time.ZoneId 4 | @import java.time.format.DateTimeFormatter 5 | 6 | @import me.ahoo.wow.api.event.DomainEvent 7 | @import me.ahoo.wow.modeling.state.ReadOnlyStateAggregate 8 | @import me.ahoo.wow.compensation.api.IExecutionFailedState 9 | @import me.ahoo.wow.compensation.api.ExecutionSuccessApplied 10 | 11 | @param host: String 12 | @param event: DomainEvent 13 | @param state: ReadOnlyStateAggregate 14 | 15 | @template.layout( 16 | title = "Execution Success", 17 | host= host, 18 | state = state 19 | ) 20 | -------------------------------------------------------------------------------- /compensation/wow-compensation-server/src/main/resources/jte/recoverable_marked.kte: -------------------------------------------------------------------------------- 1 | @import java.time.LocalDateTime 2 | @import java.time.Instant 3 | @import java.time.ZoneId 4 | @import java.time.format.DateTimeFormatter 5 | 6 | @import me.ahoo.wow.api.event.DomainEvent 7 | @import me.ahoo.wow.modeling.state.ReadOnlyStateAggregate 8 | @import me.ahoo.wow.compensation.api.IExecutionFailedState 9 | @import me.ahoo.wow.compensation.api.RecoverableMarked 10 | 11 | @param host: String 12 | @param event: DomainEvent 13 | @param state: ReadOnlyStateAggregate 14 | 15 | @template.layout( 16 | title = "Recoverable Marked", 17 | host= host, 18 | state = state 19 | ) 20 | -------------------------------------------------------------------------------- /deploy/compensation/hpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: compensation-service-hpa 5 | spec: 6 | scaleTargetRef: 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | name: compensation-service 10 | minReplicas: 2 11 | maxReplicas: 10 12 | metrics: 13 | - type: Resource 14 | resource: 15 | name: cpu 16 | target: 17 | type: Utilization 18 | averageUtilization: 80 -------------------------------------------------------------------------------- /deploy/compensation/init-schema.js: -------------------------------------------------------------------------------- 1 | use compensation_db; 2 | 3 | db.execution_failed_snapshot.createIndex({ "state.recoverable" : "hashed" }) 4 | db.execution_failed_snapshot.createIndex({ "state.isRetryable" : "hashed" }) 5 | db.execution_failed_snapshot.createIndex({ "state.status" : "hashed" }) 6 | db.execution_failed_snapshot.createIndex({ "state.retryState.timeoutAt" : 1 }) 7 | db.execution_failed_snapshot.createIndex({ "state.retryState.nextRetryAt" : 1 }) 8 | 9 | sh.enableSharding("compensation_db"); 10 | sh.shardCollection("compensation_db.execution_failed_snapshot", { "_id" : "hashed" }); 11 | sh.shardCollection("compensation_db.execution_failed_event_stream", { "aggregateId" : "hashed" }); 12 | -------------------------------------------------------------------------------- /deploy/compensation/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: compensation-service 5 | spec: 6 | selector: 7 | app: compensation-service 8 | ports: 9 | - protocol: TCP 10 | port: 80 11 | targetPort: http 12 | 13 | --- 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: compensation-service-node-port 19 | spec: 20 | type: NodePort 21 | selector: 22 | app: compensation-service 23 | ports: 24 | - nodePort: 32765 25 | port: 80 26 | protocol: TCP 27 | targetPort: http 28 | 29 | -------------------------------------------------------------------------------- /deploy/example/hpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: wow-example-hpa 5 | spec: 6 | scaleTargetRef: 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | name: wow-example 10 | minReplicas: 2 11 | maxReplicas: 10 12 | metrics: 13 | - type: Resource 14 | resource: 15 | name: cpu 16 | target: 17 | type: Utilization 18 | averageUtilization: 80 -------------------------------------------------------------------------------- /deploy/example/perf/zookeeper.yaml: -------------------------------------------------------------------------------- 1 | # helm install zookeeper-test bitnami/zookeeper -n test --set global.storageClass="alicloud-disk-essd" --set replicaCount=3 --set persistence.size=20Gi 2 | 3 | 4 | -------------------------------------------------------------------------------- /deploy/example/request/AddCartItem.http: -------------------------------------------------------------------------------- 1 | POST {{host}}/cart/{{$uuid}}/add_cart_item 2 | Content-Type: application/json 3 | Command-Wait-Stage: PROCESSED 4 | Command-Wait-Timeout: 30000 5 | Command-Request-Id: {{$uuid}} 6 | 7 | { 8 | "productId": "{{$uuid}}", 9 | "quantity": 1 10 | } 11 | 12 | > {% 13 | client.test("Request executed successfully", function() { 14 | client.assert(response.status === 200, "Response status is not 200"); 15 | }); 16 | %} 17 | 18 | ### 19 | -------------------------------------------------------------------------------- /deploy/example/request/CreateOrder.http: -------------------------------------------------------------------------------- 1 | POST {{host}}/customer/{{$uuid}}/tenant/{{$uuid}}/order 2 | Content-Type: application/json 3 | Command-Wait-Stage: PROCESSED 4 | Command-Wait-Timeout: 30000 5 | Command-Request-Id: {{$uuid}} 6 | 7 | { 8 | "fromCart": false, 9 | "items": [ 10 | { 11 | "productId": "{{$uuid}}", 12 | "price": 10, 13 | "quantity": 10 14 | } 15 | ], 16 | "address": { 17 | "country": "china", 18 | "province": "shanghai", 19 | "city": "shanghai", 20 | "district": "huangpu", 21 | "detail": "renmin road 1000" 22 | } 23 | } 24 | 25 | > {% 26 | client.test("Request executed successfully", function() { 27 | client.assert(response.status === 200, "Response status is not 200"); 28 | }); 29 | %} 30 | 31 | ### -------------------------------------------------------------------------------- /deploy/example/request/http-client.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "host": "http://127.0.0.1:8080" 4 | } 5 | } -------------------------------------------------------------------------------- /deploy/example/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: wow-example-svc 5 | spec: 6 | selector: 7 | app: wow-example 8 | ports: 9 | - protocol: TCP 10 | port: 80 11 | targetPort: http 12 | 13 | --- 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: wow-example-node-port 19 | spec: 20 | type: NodePort 21 | selector: 22 | app: wow-example 23 | ports: 24 | - nodePort: 32766 25 | port: 80 26 | protocol: TCP 27 | targetPort: http 28 | 29 | -------------------------------------------------------------------------------- /document/design/assets/CI-Flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/CI-Flow.png -------------------------------------------------------------------------------- /document/design/assets/Features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/Features.png -------------------------------------------------------------------------------- /document/design/assets/OpenAPI-Swagger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/OpenAPI-Swagger.png -------------------------------------------------------------------------------- /document/design/assets/OpenTelemetry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/OpenTelemetry.png -------------------------------------------------------------------------------- /document/design/assets/WOW-BI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/WOW-BI.png -------------------------------------------------------------------------------- /document/design/assets/compensation-dashboard-apply-retry-spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/compensation-dashboard-apply-retry-spec.png -------------------------------------------------------------------------------- /document/design/assets/compensation-dashboard-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/compensation-dashboard-error.png -------------------------------------------------------------------------------- /document/design/assets/compensation-dashboard-succeeded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/compensation-dashboard-succeeded.png -------------------------------------------------------------------------------- /document/design/assets/compensation-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/compensation-dashboard.png -------------------------------------------------------------------------------- /document/design/assets/example-transfer-jacoco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/example-transfer-jacoco.png -------------------------------------------------------------------------------- /document/design/assets/example-transfer-swagger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/design/assets/example-transfer-swagger.png -------------------------------------------------------------------------------- /document/design/uml/Aggregate-State.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | !include layout.puml 4 | 5 | title 6 | Aggregate State Flow 7 | __State Diagram__ 8 | end title 9 | 10 | state Stored 11 | state Sourced 12 | state AppendState <> 13 | state Expired 14 | 15 | Stored: Sourced.Version = Stored.Version 16 | Expired: InConsistency 17 | 18 | [*] --> Stored 19 | 20 | Stored --> Sourced: sourcing 21 | Sourced: Sourced.Version > Stored.Version 22 | 23 | Sourced --> AppendState: appendEventStream 24 | 25 | AppendState --> Stored: [success] 26 | AppendState --> Expired: [fail] 27 | 28 | Expired -> Stored: reload 29 | 30 | @enduml 31 | -------------------------------------------------------------------------------- /document/design/uml/Compensation-State.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | !include layout.puml 4 | 5 | left to right direction 6 | 7 | title 8 | ExecutionFailed State Flow 9 | __State Diagram__ 10 | end title 11 | 12 | state FAILED 13 | state PREPARED 14 | state ExecutionStatus <> 15 | state SUCCEEDED 16 | state COMPLETED #line.dotted; 17 | 18 | [*] --> FAILED 19 | 20 | FAILED --> PREPARED: PrepareCompensation 21 | PREPARED --> ExecutionStatus: Execute 22 | ExecutionStatus --> FAILED: ApplyExecutionFailed 23 | ExecutionStatus --> SUCCEEDED: ApplyExecutionSuccess 24 | SUCCEEDED --> COMPLETED 25 | FAILED --> COMPLETED: MarkUnrecoverable 26 | 27 | json CompletedCategory { 28 | "SUCCEEDED":"Succeeded", 29 | "UNRECOVERABLE":"Unrecoverable" 30 | } 31 | 32 | @enduml 33 | -------------------------------------------------------------------------------- /document/design/uml/Handler.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | autonumber 4 | 5 | ?-> Handler: MessageExchange 6 | Handler -> Handler: handle(MessageExchange) \n ExceptionHandlerWrapper 7 | Handler -> FunctionMappingFilter : filter(MessageExchange,Chain) 8 | FunctionMappingFilter -> FunctionMappingFilter: getFunction(MessageExchange) 9 | FunctionMappingFilter -> FunctionMappingFilter: writeFunctionToContext() 10 | FunctionMappingFilter -> MessageFunctionFilter: function.handle(message) 11 | 12 | @enduml 13 | -------------------------------------------------------------------------------- /document/design/uml/context-mapper.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | package OrderContext{ 3 | Order <> 4 | } 5 | 6 | package PaymentContext{ 7 | Payment <> 8 | } 9 | 10 | package OrderProcess{ 11 | CreateOrderProcess <> 12 | } 13 | 14 | PaymentContext --> OrderProcess: PaymentPaid 15 | OrderContext <- OrderProcess: PayOrder 16 | OrderContext --> OrderProcess: OrderPaid 17 | 18 | @enduml 19 | -------------------------------------------------------------------------------- /document/design/uml/layout.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam hyperlinkColor grey 3 | 4 | !$watermark= "[[https://github.com/Ahoo-Wang/Wow]]" 5 | 6 | header 7 | $watermark 8 | endheader 9 | 10 | center footer $watermark 11 | 12 | @enduml 13 | -------------------------------------------------------------------------------- /document/example/example-domain-jococo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/example-domain-jococo.png -------------------------------------------------------------------------------- /document/example/perf/Example.Cart.Add@PROCESSED.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Cart.Add@PROCESSED.pdf -------------------------------------------------------------------------------- /document/example/perf/Example.Cart.Add@PROCESSED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Cart.Add@PROCESSED.png -------------------------------------------------------------------------------- /document/example/perf/Example.Cart.Add@SENT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Cart.Add@SENT.pdf -------------------------------------------------------------------------------- /document/example/perf/Example.Cart.Add@SENT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Cart.Add@SENT.png -------------------------------------------------------------------------------- /document/example/perf/Example.Order.Create@PROCESSED.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Order.Create@PROCESSED.pdf -------------------------------------------------------------------------------- /document/example/perf/Example.Order.Create@PROCESSED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Order.Create@PROCESSED.png -------------------------------------------------------------------------------- /document/example/perf/Example.Order.Create@SENT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Order.Create@SENT.pdf -------------------------------------------------------------------------------- /document/example/perf/Example.Order.Create@SENT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/document/example/perf/Example.Order.Create@SENT.png -------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .temp 3 | cache 4 | docs/.vitepress/dist 5 | docs/.vitepress/public/dokka 6 | -------------------------------------------------------------------------------- /documentation/docs/.vitepress/configs/SITE_BASE.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | export const SITE_BASE: '/' | `/${string}/` = process.env.SITE_BASE || "/" 15 | -------------------------------------------------------------------------------- /documentation/docs/guide/advanced/aggregate-scheduler.md: -------------------------------------------------------------------------------- 1 | # 聚合调度器 -------------------------------------------------------------------------------- /documentation/docs/guide/advanced/architecture.md: -------------------------------------------------------------------------------- 1 | # 架构 2 | 3 |
4 | 5 | ![Wow-Architecture](../../public/images/Architecture.svg) 6 |
7 | 8 | -------------------------------------------------------------------------------- /documentation/docs/guide/advanced/metrics.md: -------------------------------------------------------------------------------- 1 | # 指标 -------------------------------------------------------------------------------- /documentation/docs/guide/advanced/observability.md: -------------------------------------------------------------------------------- 1 | # 可观测性 2 | 3 | ![可观测性](../../public/images/observability/observability.png) 4 | 5 | ## 安装 6 | 7 | ::: code-group 8 | ```kotlin [Gradle(Kotlin)] 9 | implementation("me.ahoo.wow:wow-opentelemetry") 10 | ``` 11 | ```groovy [Gradle(Groovy)] 12 | implementation 'me.ahoo.wow:wow-opentelemetry' 13 | ``` 14 | ```xml [Maven] 15 | 16 | me.ahoo.wow 17 | wow-opentelemetry 18 | ${wow.version} 19 | 20 | ``` 21 | ::: 22 | -------------------------------------------------------------------------------- /documentation/docs/guide/configuration.md: -------------------------------------------------------------------------------- 1 | # 配置 -------------------------------------------------------------------------------- /documentation/docs/guide/event-processor.md: -------------------------------------------------------------------------------- 1 | # 事件处理器 -------------------------------------------------------------------------------- /documentation/docs/guide/eventstore.md: -------------------------------------------------------------------------------- 1 | # 事件存储 2 | 3 | ## 事件溯源 4 | 5 |
6 | 7 | ![EventSourcing](../public/images/eventstore/eventsourcing.svg) 8 |
9 | -------------------------------------------------------------------------------- /documentation/docs/guide/extensions/spring-boot-starter.md: -------------------------------------------------------------------------------- 1 | # Spring-Boot-Starter 2 | 3 | _Spring-Boot-Starter_ 模块 集成了所有 _Wow_ 扩展,提供了自动装配的能力,使 _Wow_ 框架在 _Spring Boot_ 项目中更加便捷地使用。 4 | 5 | ::: tip 6 | 该模块的公共配置文档请参考 [配置](../../reference/config/basic)。 7 | ::: 8 | 9 | ## 安装 10 | 11 | ::: code-group 12 | ```kotlin [Gradle(Kotlin)] 13 | implementation("me.ahoo.wow:wow-spring-boot-starter") 14 | ``` 15 | ```groovy [Gradle(Groovy)] 16 | implementation 'me.ahoo.wow:wow-spring-boot-starter' 17 | ``` 18 | ```xml [Maven] 19 | 20 | me.ahoo.wow 21 | wow-spring-boot-starter 22 | ${wow.version} 23 | 24 | ``` 25 | ::: -------------------------------------------------------------------------------- /documentation/docs/guide/extensions/webflux.md: -------------------------------------------------------------------------------- 1 | # WebFlux 2 | 3 | _WebFlux_ 扩展提供了对 _WebFlux_ 的支持,依赖 `wow-openapi` 模块生成的路由规范,自动注册命令路由处理函数。 4 | 5 | ## 安装 6 | 7 | ::: code-group 8 | ```kotlin [Gradle(Kotlin)] 9 | implementation("me.ahoo.wow:wow-webflux") 10 | ``` 11 | ```groovy [Gradle(Groovy)] 12 | implementation 'me.ahoo.wow:wow-webflux' 13 | ``` 14 | ```xml [Maven] 15 | 16 | me.ahoo.wow 17 | wow-webflux 18 | ${wow.version} 19 | 20 | ``` 21 | ::: -------------------------------------------------------------------------------- /documentation/docs/guide/projection.md: -------------------------------------------------------------------------------- 1 | # 投影处理器 2 | 3 | *投影处理器*是一种将领域模型的状态以符合查询需求的形式进行组织和存储的机制。 4 | 5 | 由于 _EventStore_ 中存储的是聚合根领域事件流,对于查询非常不友好。 6 | 通过结合 _CQRS_ 架构模式,将*读模型*和*写模型*分开,允许针对查询的需求进行专门的优化。 7 | 8 | 在 _Wow_ 框架中,*读模型投影*是通过定义*投影处理器*实现的。投影处理器负责处理领域事件,更新读模型的索引状态,以反映最新的数据状态。 9 | 10 | :::tip 11 | 需要特别指出的是,当快照模式设置为 `all` 时,投影就不是必须的。 12 | 13 | 在一般场景中,聚合根的最新状态快照可以当做读模型,比如 [事件补偿控制台](./event-compensation) 就没有定义投影处理器,直接使用了最新状态快照作为读模型。 14 | ::: 15 | 16 | - 投影处理器需要标记 `@ProjectionProcessorComponent` 注解,以便框架能够自动发现。 17 | - 领域事件处理函数需要添加 `@OnEvent` 注解,但该注解不是必须的,默认情况下命名为 `onEvent` 即表明该函数为领域事件处理函数。 18 | - 领域事件处理函数接受的参数为:具体领域事件 (`OrderCreated`)、领域事件 (`DomainEvent`)。 19 | 20 | ```kotlin 21 | @ProjectionProcessorComponent 22 | class OrderProjector { 23 | 24 | fun onEvent(orderCreated: OrderCreated) { 25 | // 根据领域事件更新读模型 26 | } 27 | } 28 | ``` -------------------------------------------------------------------------------- /documentation/docs/guide/snapshot.md: -------------------------------------------------------------------------------- 1 | # 聚合快照 -------------------------------------------------------------------------------- /documentation/docs/public/baidu_verify_codeva-ufKazSOGJx.html: -------------------------------------------------------------------------------- 1 | ce305020a64b4862606c47818dc70022 -------------------------------------------------------------------------------- /documentation/docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/favicon.ico -------------------------------------------------------------------------------- /documentation/docs/public/images/Features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/Features.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/dashboard-apply-retry-spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/dashboard-apply-retry-spec.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/dashboard-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/dashboard-error.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/dashboard-succeeded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/dashboard-succeeded.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/dashboard-unrecoverable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/dashboard-unrecoverable.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/dashboard.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/execution-failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/execution-failed.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/execution-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/execution-success.png -------------------------------------------------------------------------------- /documentation/docs/public/images/compensation/open-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/compensation/open-api.png -------------------------------------------------------------------------------- /documentation/docs/public/images/example/transfer-jacoco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/example/transfer-jacoco.png -------------------------------------------------------------------------------- /documentation/docs/public/images/example/transfer-swagger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/example/transfer-swagger.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/ci-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/ci-flow.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/manage-project-templates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/manage-project-templates.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/new-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/new-project.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/run-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/run-server.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/swagger-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/swagger-ui.png -------------------------------------------------------------------------------- /documentation/docs/public/images/getting-started/test-coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/getting-started/test-coverage.png -------------------------------------------------------------------------------- /documentation/docs/public/images/observability/observability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/observability/observability.png -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Cart.Add@PROCESSED.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Cart.Add@PROCESSED.pdf -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Cart.Add@PROCESSED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Cart.Add@PROCESSED.png -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Cart.Add@SENT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Cart.Add@SENT.pdf -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Cart.Add@SENT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Cart.Add@SENT.png -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Order.Create@PROCESSED.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Order.Create@PROCESSED.pdf -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Order.Create@PROCESSED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Order.Create@PROCESSED.png -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Order.Create@SENT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Order.Create@SENT.pdf -------------------------------------------------------------------------------- /documentation/docs/public/images/perf/Example.Order.Create@SENT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/perf/Example.Order.Create@SENT.png -------------------------------------------------------------------------------- /documentation/docs/public/images/query/open-api-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/query/open-api-query.png -------------------------------------------------------------------------------- /documentation/docs/public/images/saga/choreography.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/saga/choreography.png -------------------------------------------------------------------------------- /documentation/docs/public/images/saga/orchestration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/documentation/docs/public/images/saga/orchestration.png -------------------------------------------------------------------------------- /documentation/docs/public/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wow", 3 | "short_name": "Wow", 4 | "description": "领域模型即服务 | Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing. | 基于 DDD、EventSourcing 的现代响应式 CQRS 架构微服务开发框架", 5 | "start_url": "/index.html", 6 | "display": "standalone", 7 | "background_color": "#fff", 8 | "theme_color": "#3eaf7c", 9 | "icons": [ 10 | { 11 | "src": "/images/logo.svg", 12 | "sizes": "192x192", 13 | "type": "image/svg" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /documentation/docs/reference/awesome/microservices.md: -------------------------------------------------------------------------------- 1 | # Awesome Microservices 2 | 3 | ## 开源项目 4 | 5 | - [Wow](https://github.com/Ahoo-Wang/Wow): 基于 DDD & EventSourcing 的现代响应式 CQRS 架构微服务开发框架 6 | - [CosId](https://github.com/Ahoo-Wang/CosId): 通用、灵活、高性能的分布式 ID 生成器 7 | - [CoSky](https://github.com/Ahoo-Wang/CoSky): 高性能、低成本微服务治理平台 8 | - [CoSec](https://github.com/Ahoo-Wang/CoSec): 基于 RBAC 和策略的多租户响应式安全框架 9 | - [CoCache](https://github.com/Ahoo-Wang/CoCache): 分布式一致性二级缓存框架 10 | - [Simba](https://github.com/Ahoo-Wang/Simba): 易用、灵活的分布式锁服务 11 | - [CoApi](https://github.com/Ahoo-Wang/CoApi): 简化 Spring 6 中 HTTP 客户端定义,提供零样板代码自动配置,让接口调用更便捷高效 12 | - [Nacos](https://github.com/alibaba/nacos): 阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台 -------------------------------------------------------------------------------- /documentation/docs/reference/awesome/reactive.md: -------------------------------------------------------------------------------- 1 | # Awesome Reactive 2 | 3 | - [响应式宣言](https://www.reactivemanifesto.org/zh-CN) 4 | - [R2DBC](https://r2dbc.io/) 5 | - [ReactiveX](http://reactivex.io/) 6 | - [Reactive Streams](http://www.reactive-streams.org/) 7 | - [Project Reactor](https://projectreactor.io/) 8 | - [RxJava](https://github.com/ReactiveX/RxJava) 9 | -------------------------------------------------------------------------------- /documentation/docs/reference/config/event.md: -------------------------------------------------------------------------------- 1 | # 事件总线 2 | 3 | - 配置类:[EventProperties](https://github.com/Ahoo-Wang/Wow/blob/main/wow-spring-boot-starter/src/main/kotlin/me/ahoo/wow/spring/boot/starter/event/EventProperties.kt) 4 | - 前缀:`wow.event.` 5 | 6 | | 名称 | 数据类型 | 说明 | 默认值 | 7 | |---------------|-------------------------|----------------------------------------|-----| 8 | | `bus` | `BusProperties` | [BusProperties](./basic#busproperties) | | 9 | 10 | **YAML 配置样例** 11 | 12 | ```yaml 13 | wow: 14 | event: 15 | bus: 16 | type: kafka 17 | local-first: 18 | enabled: true 19 | ``` -------------------------------------------------------------------------------- /documentation/docs/reference/example/order.md: -------------------------------------------------------------------------------- 1 | # 订单系统 2 | 3 | _[订单系统案例](https://github.com/Ahoo-Wang/Wow/blob/main/example/)_ 是一个基于 _Wow_ 框架的示例项目,旨在帮助开发者快速上手 _Wow_ 框架。 -------------------------------------------------------------------------------- /documentation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "version": "5.0.0", 4 | "description": "领域模型即服务 | Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing.", 5 | "main": "index.js", 6 | "scripts": { 7 | "docs:dev": "vitepress dev docs", 8 | "docs:build": "vitepress build docs", 9 | "docs:preview": "vitepress preview docs" 10 | }, 11 | "keywords": [ 12 | "Domain-Driven", 13 | "Event-Driven", 14 | "Test-Driven", 15 | "Declarative-Design", 16 | "Reactive Programming", 17 | "Command Query Responsibility Segregation", 18 | "Event Sourcing" 19 | ], 20 | "author": "ahoo-wang", 21 | "license": "Apache-2.0", 22 | "devDependencies": { 23 | "vitepress": "^1.5.0" 24 | }, 25 | "dependencies": { 26 | "medium-zoom": "^1.1.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example/example-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(platform(project(":wow-dependencies"))) 6 | api("io.swagger.core.v3:swagger-core-jakarta") 7 | implementation(project(":wow-api")) 8 | implementation(project(":wow-apiclient")) 9 | implementation("com.fasterxml.jackson.core:jackson-annotations") 10 | api("jakarta.validation:jakarta.validation-api") 11 | api("me.ahoo.coapi:coapi-api") 12 | implementation("org.springframework:spring-web") 13 | ksp(project(":wow-compiler")) 14 | } 15 | -------------------------------------------------------------------------------- /example/example-api/src/main/kotlin/me/ahoo/wow/example/api/cart/AddCartItem.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.example.api.cart 2 | 3 | import jakarta.validation.constraints.NotBlank 4 | import jakarta.validation.constraints.Positive 5 | import me.ahoo.wow.api.annotation.AllowCreate 6 | import me.ahoo.wow.api.annotation.CommandRoute 7 | import me.ahoo.wow.api.annotation.Order 8 | import me.ahoo.wow.api.annotation.Summary 9 | 10 | @Order(1) 11 | @AllowCreate 12 | @CommandRoute( 13 | method = CommandRoute.Method.POST, 14 | summary = "加入购物车", 15 | description = "加入购物车" 16 | ) 17 | data class AddCartItem( 18 | @field:NotBlank 19 | val productId: String, 20 | @field:Positive 21 | val quantity: Int = 1 22 | ) 23 | 24 | @Summary("商品已加入购物车") 25 | data class CartItemAdded( 26 | val added: CartItem 27 | ) 28 | -------------------------------------------------------------------------------- /example/example-api/src/main/kotlin/me/ahoo/wow/example/api/cart/CartItem.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.example.api.cart 2 | 3 | data class CartItem( 4 | val productId: String, 5 | val quantity: Int = 1 6 | ) 7 | -------------------------------------------------------------------------------- /example/example-api/src/main/kotlin/me/ahoo/wow/example/api/cart/ChangeQuantity.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.example.api.cart 2 | 3 | import jakarta.validation.constraints.NotBlank 4 | import jakarta.validation.constraints.Positive 5 | import me.ahoo.wow.api.annotation.CommandRoute 6 | import me.ahoo.wow.api.annotation.Order 7 | import me.ahoo.wow.api.annotation.Summary 8 | 9 | @Order(2) 10 | @Summary("变更购买数量") 11 | @CommandRoute(appendIdPath = CommandRoute.AppendPath.ALWAYS) 12 | data class ChangeQuantity( 13 | @field:NotBlank 14 | val productId: String, 15 | @field:Positive 16 | val quantity: Int 17 | ) 18 | 19 | data class CartQuantityChanged( 20 | val changed: CartItem 21 | ) 22 | -------------------------------------------------------------------------------- /example/example-api/src/main/kotlin/me/ahoo/wow/example/api/cart/RemoveCartItem.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.example.api.cart 2 | 3 | import jakarta.validation.constraints.NotEmpty 4 | import me.ahoo.wow.api.annotation.Order 5 | import me.ahoo.wow.api.annotation.Summary 6 | 7 | @Order(3) 8 | @Summary("删除商品") 9 | data class RemoveCartItem( 10 | @field:NotEmpty 11 | val productIds: Set 12 | ) 13 | 14 | data class CartItemRemoved( 15 | val productIds: Set 16 | ) 17 | -------------------------------------------------------------------------------- /example/example-api/src/main/kotlin/me/ahoo/wow/example/api/cart/ViewCart.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.api.cart 15 | 16 | import me.ahoo.wow.api.annotation.VoidCommand 17 | 18 | @VoidCommand 19 | class ViewCart 20 | -------------------------------------------------------------------------------- /example/example-domain/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(project(":example-api")) 6 | api(project(":wow-spring")) 7 | ksp(project(":wow-compiler")) 8 | testImplementation(project(":wow-test")) 9 | testImplementation("io.projectreactor:reactor-test") 10 | } 11 | 12 | tasks.jacocoTestCoverageVerification { 13 | dependsOn(tasks.test, tasks.jacocoTestReport) 14 | violationRules { 15 | rule { 16 | limit { 17 | minimum = 0.8.toBigDecimal() 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /example/example-domain/src/test/kotlin/me/ahoo/wow/example/domain/order/MainFixtures.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.domain.order 15 | 16 | object MainFixtures 17 | -------------------------------------------------------------------------------- /example/example-server/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG APP_NAME=example-server 2 | ARG WORK_HOME=/opt/${APP_NAME} 3 | 4 | FROM dragonwell-registry.cn-hangzhou.cr.aliyuncs.com/dragonwell/dragonwell:21-ubuntu AS base 5 | 6 | FROM base as build 7 | ARG WORK_HOME 8 | ARG APP_NAME 9 | 10 | WORKDIR ${WORK_HOME} 11 | COPY build/install/${APP_NAME} . 12 | 13 | FROM base as run 14 | ARG WORK_HOME 15 | 16 | COPY --from=build ${WORK_HOME} ${WORK_HOME} 17 | 18 | WORKDIR ${WORK_HOME} 19 | EXPOSE 8080 20 | 21 | ENTRYPOINT ["bin/example-server"] 22 | -------------------------------------------------------------------------------- /example/example-server/src/dist/logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/example/example-server/src/dist/logs/.gitignore -------------------------------------------------------------------------------- /example/example-server/src/init-schema/init-schema.js: -------------------------------------------------------------------------------- 1 | // use wow_example_db; 2 | sh.enableSharding("wow_example_db"); 3 | sh.shardCollection("wow_example_db.order_snapshot", { "_id" : "hashed" }); 4 | sh.shardCollection("wow_example_db.order_event_stream", { "aggregateId" : "hashed" }); 5 | sh.shardCollection("wow_example_db.cart_snapshot", { "_id" : "hashed" }); 6 | sh.shardCollection("wow_example_db.cart_event_stream", { "aggregateId" : "hashed" }); -------------------------------------------------------------------------------- /example/example-server/src/main/kotlin/me/ahoo/wow/example/server/order/OrderRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.server.order 15 | 16 | // @Repository 17 | // class OrderRepository 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(platform(project(":wow-dependencies"))) 6 | api("io.swagger.core.v3:swagger-core-jakarta") 7 | implementation(project(":wow-api")) 8 | implementation("com.fasterxml.jackson.core:jackson-annotations") 9 | api("jakarta.validation:jakarta.validation-api") 10 | ksp(project(":wow-compiler")) 11 | } 12 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/src/main/java/me/ahoo/wow/example/transfer/api/AccountFrozen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.transfer.api; 15 | 16 | public record AccountFrozen(String reason) { 17 | } 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/src/main/java/me/ahoo/wow/example/transfer/api/AccountUnfrozen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.transfer.api; 15 | 16 | public record AccountUnfrozen(String reason) { 17 | } 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/src/main/java/me/ahoo/wow/example/transfer/api/AmountLocked.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.transfer.api; 15 | 16 | public record AmountLocked(long amount) { 17 | } 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/src/main/java/me/ahoo/wow/example/transfer/api/AmountUnlocked.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.transfer.api; 15 | 16 | public record AmountUnlocked(long amount) { 17 | } 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-api/src/main/java/me/ahoo/wow/example/transfer/api/Confirmed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.example.transfer.api; 15 | 16 | public record Confirmed(long amount) { 17 | } 18 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-domain/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(project(":example-transfer-api")) 6 | api(project(":wow-spring")) 7 | ksp(project(":wow-compiler")) 8 | testImplementation(project(":wow-test")) 9 | testImplementation("io.projectreactor:reactor-test") 10 | } 11 | 12 | tasks.jacocoTestCoverageVerification { 13 | dependsOn(tasks.test, tasks.jacocoTestReport) 14 | violationRules { 15 | rule { 16 | limit { 17 | minimum = 0.8.toBigDecimal() 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/transfer/example-transfer-server/src/dist/config/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: transfer-service 4 | logging: 5 | level: 6 | me.ahoo.wow: debug 7 | 8 | cosid: 9 | machine: 10 | enabled: true 11 | distributor: 12 | type: manual 13 | manual: 14 | machine-id: 1 15 | generator: 16 | enabled: true 17 | wow: 18 | command: 19 | bus: 20 | type: in_memory 21 | event: 22 | bus: 23 | type: in_memory 24 | kafka: 25 | enabled: false 26 | eventsourcing: 27 | store: 28 | storage: in_memory 29 | snapshot: 30 | storage: in_memory 31 | state: 32 | bus: 33 | type: in_memory -------------------------------------------------------------------------------- /example/transfer/example-transfer-server/src/dist/logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/example/transfer/example-transfer-server/src/dist/logs/.gitignore -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahoo-Wang/Wow/f3f87801e734310cfd9f5e1e42f161a9f3f585c6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /schema/query/single-query.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "$id": "https://github.com/Ahoo-Wang/Wow/blob/main/schema/query/single-query.schema.json", 4 | "title": "Single Query Model Schema", 5 | "type": "object", 6 | "properties": { 7 | "condition": { 8 | "$ref": "definitions.schema.json#/definitions/condition", 9 | "default": { 10 | "operator": "ALL" 11 | } 12 | }, 13 | "projection": { 14 | "$ref": "definitions.schema.json#/definitions/projection", 15 | "default": { 16 | "include": [], 17 | "exclude": [] 18 | } 19 | }, 20 | "sort": { 21 | "type": "array", 22 | "items": { 23 | "$ref": "definitions.schema.json#/definitions/sort" 24 | }, 25 | "default": [] 26 | } 27 | }, 28 | "required": [ 29 | "condition" 30 | ] 31 | } -------------------------------------------------------------------------------- /test/wow-it/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Integration Testing" 2 | 3 | dependencies { 4 | testImplementation(project(":wow-core")) 5 | testImplementation("io.projectreactor:reactor-test") 6 | testImplementation("me.ahoo.cosid:cosid-test") 7 | testImplementation("org.hamcrest:hamcrest") 8 | testImplementation(project(":wow-mongo")) 9 | testImplementation(project(":wow-kafka")) 10 | testImplementation(project(":wow-tck")) 11 | testImplementation("org.testcontainers:testcontainers") 12 | testImplementation("org.testcontainers:junit-jupiter") 13 | testImplementation("org.testcontainers:mongodb") 14 | testImplementation("org.testcontainers:kafka") 15 | } 16 | -------------------------------------------------------------------------------- /test/wow-mock/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Integration Testing" 2 | 3 | dependencies { 4 | api(project(":wow-core")) 5 | testImplementation("io.projectreactor:reactor-test") 6 | testImplementation("me.ahoo.cosid:cosid-test") 7 | testImplementation("org.hamcrest:hamcrest") 8 | testImplementation(project(":wow-tck")) 9 | } 10 | -------------------------------------------------------------------------------- /test/wow-mock/src/test/kotlin/me/ahoo/wow/eventsourcing/mock/DelaySnapshotRepositoryTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.eventsourcing.mock 2 | 3 | import me.ahoo.wow.eventsourcing.snapshot.SnapshotRepository 4 | import me.ahoo.wow.tck.eventsourcing.snapshot.SnapshotRepositorySpec 5 | 6 | class DelaySnapshotRepositoryTest : SnapshotRepositorySpec() { 7 | override fun createSnapshotRepository(): SnapshotRepository { 8 | return DelaySnapshotRepository() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/wow-tck/src/main/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts": { 3 | "wow-tck": { 4 | "alias": "tck", 5 | "scopes": [ 6 | "me.ahoo.wow.tck" 7 | ], 8 | "aggregates": { 9 | "mock_aggregate": { 10 | "type": "me.ahoo.wow.tck.mock.MockCommandAggregate", 11 | "scopes": [ 12 | "me.ahoo.wow.tck" 13 | ] 14 | } 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/wow-test/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Wow Test Suite" 2 | 3 | dependencies { 4 | api(project(":wow-core")) 5 | api("io.projectreactor:reactor-test") 6 | api("me.ahoo.cosid:cosid-test") 7 | api("me.ahoo.test:fluent-assert-core") 8 | api("org.hibernate.validator:hibernate-validator") 9 | implementation("org.junit.jupiter:junit-jupiter-api") 10 | implementation("com.fasterxml.jackson.core:jackson-databind") 11 | implementation("io.micrometer:micrometer-core") 12 | } 13 | -------------------------------------------------------------------------------- /test/wow-test/src/main/resources/META-INF/services/me.ahoo.wow.id.GlobalIdGeneratorFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | me.ahoo.wow.test.id.TestGlobalIdGeneratorFactory 15 | -------------------------------------------------------------------------------- /wow-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies{ 2 | compileOnly("io.swagger.core.v3:swagger-annotations-jakarta") 3 | } -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/Ordered.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api 15 | 16 | import me.ahoo.wow.api.annotation.Order 17 | 18 | interface Ordered { 19 | val order: Order 20 | } 21 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/modeling/MaterializeState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.modeling 15 | 16 | interface MaterializeState { 17 | fun materialize(): MATERIALIZED 18 | } 19 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/naming/DescriptionCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.naming 15 | 16 | interface DescriptionCapable { 17 | val description: String 18 | } 19 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/naming/EnabledCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.naming 15 | 16 | interface EnabledCapable { 17 | val enabled: Boolean 18 | } 19 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/naming/Materialized.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.naming 15 | 16 | interface Materialized 17 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/naming/Named.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.naming 15 | 16 | interface Named { 17 | val name: String 18 | } 19 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/naming/SummaryCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.naming 15 | 16 | interface SummaryCapable { 17 | val summary: String 18 | } 19 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/query/DeletionState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.api.query 15 | 16 | enum class DeletionState { 17 | ACTIVE, 18 | DELETED, 19 | ALL 20 | } 21 | -------------------------------------------------------------------------------- /wow-api/src/main/kotlin/me/ahoo/wow/api/query/PagedList.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.api.query 2 | 3 | interface IPagedList { 4 | val total: Long 5 | val list: List 6 | } 7 | 8 | data class PagedList( 9 | override val total: Long, 10 | override val list: List, 11 | ) : IPagedList { 12 | companion object { 13 | private val EMPTY: PagedList = PagedList(0, emptyList()) 14 | 15 | fun empty(): PagedList = EMPTY 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wow-api/src/test/kotlin/me/ahoo/wow/api/messaging/function/FunctionInfoDataKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.api.messaging.function 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class FunctionInfoDataKtTest { 7 | 8 | @Test 9 | fun materialize() { 10 | val functionInfoData = FunctionInfoData(FunctionKind.COMMAND, "contextName", "processorName", "functionName") 11 | val materialized = functionInfoData.materialize() 12 | functionInfoData.assert().isSameAs(materialized) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wow-api/src/test/kotlin/me/ahoo/wow/api/query/PagedListTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.api.query 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class PagedListTest { 7 | @Test 8 | fun empty() { 9 | PagedList.empty().assert().isSameAs(PagedList.empty()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /wow-apiclient/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Wow RESTful ApiClient" 2 | 3 | dependencies { 4 | api(project(":wow-core")) 5 | api(project(":wow-openapi")) 6 | api("io.projectreactor:reactor-core") 7 | implementation("me.ahoo.coapi:coapi-api") 8 | implementation("org.springframework:spring-web") 9 | implementation("org.springframework:spring-webflux") 10 | testImplementation(project(":wow-tck")) 11 | } 12 | -------------------------------------------------------------------------------- /wow-apiclient/src/main/kotlin/me/ahoo/wow/apiclient/query/SnapshotQueryApi.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.apiclient.query 15 | 16 | const val SNAPSHOT_RESOURCE_NAME = "snapshot" 17 | 18 | interface SnapshotQueryApi 19 | -------------------------------------------------------------------------------- /wow-apiclient/src/main/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts": { 3 | "wow.apiclient": { 4 | "alias": "wow.apiclient", 5 | "scopes": [ 6 | "me.ahoo.wow.apiclient" 7 | ] 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /wow-bi/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Wow BI Sync Script Generator" 2 | 3 | dependencies { 4 | implementation(project(":wow-core")) 5 | implementation(libs.jte) 6 | implementation(libs.jte.kotlin) 7 | testImplementation(project(":example-domain")) 8 | testImplementation(project(":wow-compensation-domain")) 9 | } -------------------------------------------------------------------------------- /wow-bi/src/main/resources/clickhouse/global.kte: -------------------------------------------------------------------------------- 1 | 2 | CREATE DATABASE IF NOT EXISTS bi_db ON CLUSTER '{cluster}'; 3 | CREATE DATABASE IF NOT EXISTS bi_db_consumer ON CLUSTER '{cluster}'; -------------------------------------------------------------------------------- /wow-bi/src/test/kotlin/me/ahoo/wow/bi/ScriptEngineTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.bi 2 | 3 | import me.ahoo.test.asserts.assert 4 | import me.ahoo.wow.configuration.MetadataSearcher 5 | import org.junit.jupiter.api.Test 6 | 7 | class ScriptEngineTest { 8 | 9 | @Test 10 | fun generate() { 11 | val syncScript = ScriptEngine.generate(MetadataSearcher.localAggregates) 12 | syncScript.assert().isNotNull() 13 | } 14 | 15 | @Test 16 | fun generateUseCustomParameters() { 17 | val syncScript = ScriptEngine.generate( 18 | MetadataSearcher.localAggregates, 19 | "kafkaBootstrapServers", 20 | "topicPrefix", 21 | MessageHeaderSqlType.STRING 22 | ) 23 | syncScript.assert().isNotNull() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /wow-bi/src/test/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts" : { 3 | "bi-service" : { 4 | "alias" : "bi", 5 | "scopes" : [ "me.ahoo.wow.bi.expansion" ], 6 | "aggregates" : { 7 | "aggregate" : { 8 | "scopes" : [ "me.ahoo.wow.bi.expansion" ], 9 | "type" : "me.ahoo.wow.bi.expansion.BIAggregate", 10 | "tenantId" : "(0)", 11 | "id" : null, 12 | "commands" : [ ], 13 | "events" : [ ] 14 | } 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /wow-cocache/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | dependencies { 3 | api(project(":wow-apiclient")) 4 | api(project(":wow-query")) 5 | api("me.ahoo.cocache:cocache-core") 6 | testImplementation(project(":wow-tck")) 7 | } 8 | -------------------------------------------------------------------------------- /wow-cocache/src/main/kotlin/me/ahoo/wow/cache/StateToCacheDataConverter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.cache 15 | 16 | fun interface StateToCacheDataConverter { 17 | fun stateToCacheData(state: S): D 18 | } 19 | -------------------------------------------------------------------------------- /wow-compiler/src/test/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts": { 3 | "order-service": { 4 | "scopes": [ 5 | "me.ahoo.wow.domains.order" 6 | ], 7 | "aggregates": { 8 | "order": { 9 | "type": "me.ahoo.wow.domains.order.model.Order", 10 | "scopes": [ 11 | "me.ahoo.wow.domains.order" 12 | ] 13 | } 14 | } 15 | }, 16 | "payment-service": { 17 | "scopes": [ 18 | "me.ahoo.wow.domains.payment" 19 | ], 20 | "aggregates": { 21 | "payment": { 22 | "scopes": [ 23 | "me.ahoo.wow.domains.payment" 24 | ] 25 | } 26 | } 27 | }, 28 | "warehouse-service": { 29 | "scopes": [ 30 | "me.ahoo.wow.domains.warehouse" 31 | ] 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /wow-core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Wow Shared Kernel" 2 | 3 | dependencies { 4 | api(project(":wow-api")) 5 | api("me.ahoo.cosid:cosid-core") 6 | api("io.projectreactor:reactor-core") 7 | api("io.projectreactor.kotlin:reactor-kotlin-extensions") 8 | api("jakarta.validation:jakarta.validation-api") 9 | api("com.google.guava:guava") 10 | api("com.fasterxml.jackson.core:jackson-databind") 11 | api("io.github.oshai:kotlin-logging-jvm") 12 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 13 | implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") 14 | testImplementation(project(":wow-tck")) 15 | } 16 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/command/CommandResultCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.command 15 | 16 | interface CommandResultCapable { 17 | val result: Map 18 | } 19 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/infra/reflection/VisitorLifeCycle.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | package me.ahoo.wow.infra.reflection 14 | 15 | interface VisitorLifeCycle { 16 | fun start() = Unit 17 | fun end() = Unit 18 | } 19 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/metadata/Metadata.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.metadata 15 | 16 | interface Metadata 17 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/metrics/Metrizable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.metrics 15 | 16 | interface Metrizable 17 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/naming/CurrentContextCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.naming 15 | 16 | interface CurrentContextCapable { 17 | val current: CONTEXT 18 | } 19 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/saga/stateful/SagaManager.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | package me.ahoo.wow.saga.stateful 14 | 15 | /** 16 | * Saga Manager . 17 | * 18 | * @author ahoo wang 19 | */ 20 | interface SagaManager 21 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/saga/stateful/SagaRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | package me.ahoo.wow.saga.stateful 14 | 15 | /** 16 | * SagaRepository . 17 | * 18 | * @author ahoo wang 19 | */ 20 | interface SagaRepository 21 | -------------------------------------------------------------------------------- /wow-core/src/main/kotlin/me/ahoo/wow/saga/stateful/StatefulSaga.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.saga.stateful 15 | 16 | /** 17 | * TODO : StatefulSaga is StateMachine 18 | */ 19 | interface StatefulSaga 20 | -------------------------------------------------------------------------------- /wow-core/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | me.ahoo.wow.serialization.WowModule -------------------------------------------------------------------------------- /wow-core/src/main/resources/META-INF/services/me.ahoo.wow.id.AggregateIdGeneratorFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | me.ahoo.wow.id.CosIdAggregateIdGeneratorFactory 14 | -------------------------------------------------------------------------------- /wow-core/src/main/resources/META-INF/services/me.ahoo.wow.id.GlobalIdGeneratorFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | me.ahoo.wow.id.CosIdGlobalIdGeneratorFactory 14 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/command/SimpleCommandMessageTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.command 2 | 3 | import me.ahoo.wow.id.GlobalIdGenerator 4 | import me.ahoo.wow.id.generateGlobalId 5 | import me.ahoo.wow.messaging.DefaultHeader 6 | import org.hamcrest.MatcherAssert.* 7 | import org.hamcrest.Matchers.* 8 | import org.junit.jupiter.api.Test 9 | 10 | class SimpleCommandMessageTest { 11 | @Test 12 | fun toCommandMessage() { 13 | val ownerId = generateGlobalId() 14 | val command = 15 | MockCreateCommand(GlobalIdGenerator.generateAsString()).toCommandMessage(ownerId = ownerId) 16 | assertThat(command.isReadOnly, equalTo(false)) 17 | command.withHeader(DefaultHeader.empty()) 18 | command.withReadOnly() 19 | assertThat(command.isReadOnly, equalTo(true)) 20 | assertThat(command.ownerId, equalTo(ownerId)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/command/validation/ValidatorsKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.command.validation 2 | 3 | import jakarta.validation.constraints.Positive 4 | import me.ahoo.wow.command.CommandValidationException 5 | import me.ahoo.wow.test.validation.TestValidator 6 | import org.junit.jupiter.api.Assertions 7 | import org.junit.jupiter.api.Test 8 | 9 | class ValidatorsKtTest { 10 | 11 | @Test 12 | fun validateCommand() { 13 | TestValidator.validateCommand(MockCommandBody(qty = 1)) 14 | } 15 | 16 | @Test 17 | fun validateCommandError() { 18 | Assertions.assertThrows(CommandValidationException::class.java) { 19 | TestValidator.validateCommand(MockCommandBody(qty = -1)) 20 | } 21 | } 22 | 23 | data class MockCommandBody( 24 | @field:Positive 25 | val qty: Int 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/command/wait/CommandWaitNotifierKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.command.wait 2 | 3 | import org.hamcrest.CoreMatchers.equalTo 4 | import org.hamcrest.MatcherAssert.* 5 | import org.junit.jupiter.api.Test 6 | 7 | class CommandWaitNotifierKtTest { 8 | 9 | @Test 10 | fun isLocalCommandIfBlank() { 11 | assertThat(isLocalCommand(""), equalTo(false)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/configuration/WowMetadataTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.configuration 2 | 3 | import org.junit.jupiter.api.Test 4 | 5 | class WowMetadataTest { 6 | 7 | @Test 8 | fun merge() { 9 | WowMetadata().merge(WowMetadata()) 10 | } 11 | 12 | @Test 13 | fun mergeEmptyContext() { 14 | WowMetadata(mapOf("test" to BoundedContext())).merge(WowMetadata(mapOf("test" to BoundedContext()))) 15 | } 16 | 17 | @Test 18 | fun mergeContextIfEmtpyAlias() { 19 | WowMetadata(mapOf("test" to BoundedContext(""))).merge(WowMetadata(mapOf("test" to BoundedContext("")))) 20 | } 21 | 22 | @Test 23 | fun mergeContextIfEmtpyNullAlias() { 24 | WowMetadata(mapOf("test" to BoundedContext(""))).merge(WowMetadata(mapOf("test" to BoundedContext()))) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/event/DomainEventStreamFactoryKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.event 2 | 3 | import org.hamcrest.CoreMatchers.equalTo 4 | import org.hamcrest.MatcherAssert.* 5 | import org.junit.jupiter.api.Test 6 | 7 | class DomainEventStreamFactoryKtTest { 8 | 9 | @Test 10 | fun flatEventList() { 11 | val flat = listOf(1, 2).flatEvent().toList() 12 | assertThat(flat.size, equalTo(2)) 13 | } 14 | 15 | @Test 16 | fun flatEventArray() { 17 | val flat = arrayOf(1, 2).flatEvent().toList() 18 | assertThat(flat.size, equalTo(2)) 19 | } 20 | 21 | @Test 22 | fun flatEventOther() { 23 | val flat = Any().flatEvent().toList() 24 | assertThat(flat.size, equalTo(1)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/event/NoOpDomainEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.event 2 | 3 | import io.mockk.mockk 4 | import org.junit.jupiter.api.Test 5 | import reactor.kotlin.test.test 6 | 7 | class NoOpDomainEventBusTest { 8 | 9 | @Test 10 | fun send() { 11 | NoOpDomainEventBus.send(mockk()) 12 | .test() 13 | .verifyComplete() 14 | } 15 | 16 | @Test 17 | fun receive() { 18 | NoOpDomainEventBus.receive(mockk()) 19 | .test() 20 | .verifyComplete() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/eventsourcing/EventStoreStateAggregateRepositoryTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.eventsourcing 2 | 3 | import me.ahoo.wow.modeling.state.StateAggregateFactory 4 | import me.ahoo.wow.modeling.state.StateAggregateRepository 5 | import me.ahoo.wow.tck.eventsourcing.StateAggregateRepositorySpec 6 | 7 | class EventStoreStateAggregateRepositoryTest : StateAggregateRepositorySpec() { 8 | override fun createStateAggregateRepository( 9 | aggregateFactory: StateAggregateFactory, 10 | eventStore: EventStore 11 | ): StateAggregateRepository { 12 | return EventStoreStateAggregateRepository(aggregateFactory, eventStore) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/eventsourcing/state/InMemoryStateEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.eventsourcing.state 2 | 3 | import me.ahoo.wow.tck.eventsourcing.state.StateEventBusSpec 4 | 5 | class InMemoryStateEventBusTest : StateEventBusSpec() { 6 | override fun createMessageBus(): StateEventBus { 7 | return InMemoryStateEventBus() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/exception/NotFoundResourceExceptionTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.exception 2 | 3 | import org.junit.jupiter.api.Test 4 | import reactor.core.publisher.Flux 5 | import reactor.core.publisher.Mono 6 | import reactor.kotlin.test.test 7 | 8 | class NotFoundResourceExceptionTest { 9 | @Test 10 | fun monoThrowNotFoundIfEmpty() { 11 | Mono.empty() 12 | .throwNotFoundIfEmpty("Not found.") 13 | .test() 14 | .expectError(NotFoundResourceException::class.java) 15 | .verify() 16 | } 17 | 18 | @Test 19 | fun fluxThrowNotFoundIfEmpty() { 20 | Flux.empty() 21 | .throwNotFoundIfEmpty() 22 | .test() 23 | .expectError(NotFoundResourceException::class.java) 24 | .verify() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/exception/PreconditionsTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.exception 2 | 3 | import org.hamcrest.MatcherAssert.* 4 | import org.hamcrest.Matchers.* 5 | import org.junit.jupiter.api.Assertions 6 | import org.junit.jupiter.api.Test 7 | 8 | class PreconditionsTest { 9 | 10 | @Test 11 | fun check() { 12 | val exception = Assertions.assertThrows(WowException::class.java) { 13 | Preconditions.check(false, "errorCode") { 14 | "error message" 15 | } 16 | } 17 | assertThat(exception.errorCode, equalTo("errorCode")) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/infra/idempotency/NoOpIdempotencyCheckerTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.infra.idempotency 2 | 3 | import me.ahoo.wow.id.GlobalIdGenerator 4 | import org.junit.jupiter.api.Test 5 | import reactor.kotlin.test.test 6 | 7 | class NoOpIdempotencyCheckerTest { 8 | 9 | @Test 10 | fun check() { 11 | val requestId = GlobalIdGenerator.generateAsString() 12 | NoOpIdempotencyChecker.check(requestId) 13 | .test() 14 | .expectNext(true) 15 | .verifyComplete() 16 | NoOpIdempotencyChecker.check(requestId) 17 | .test() 18 | .expectNext(true) 19 | .verifyComplete() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/infra/reflection/ClassMetadataTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.infra.reflection 2 | 3 | import me.ahoo.wow.infra.reflection.ClassMetadata.visit 4 | import org.junit.jupiter.api.Test 5 | 6 | class ClassMetadataTest { 7 | 8 | @Test 9 | fun visit() { 10 | MockClass::class.visit( 11 | object : 12 | ClassVisitor { 13 | }, 14 | ) 15 | } 16 | 17 | class MockClass(val id: String, var name: String) { 18 | private fun privateFun() = Unit 19 | fun publicFun() = Unit 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/messaging/propagation/MessagePropagatorProviderTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.messaging.propagation 2 | 3 | import me.ahoo.wow.command.toCommandMessage 4 | import me.ahoo.wow.id.GlobalIdGenerator 5 | import me.ahoo.wow.messaging.DefaultHeader 6 | import me.ahoo.wow.messaging.propagation.MessagePropagatorProvider.inject 7 | import me.ahoo.wow.tck.mock.MockCreateAggregate 8 | import org.junit.jupiter.api.Test 9 | 10 | class MessagePropagatorProviderTest { 11 | 12 | @Test 13 | fun inject() { 14 | val header = DefaultHeader.empty() 15 | val upstreamMessage = 16 | MockCreateAggregate(GlobalIdGenerator.generateAsString(), GlobalIdGenerator.generateAsString()) 17 | .toCommandMessage() 18 | header.inject(upstreamMessage) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/modeling/command/ExchangeCommandAggregateKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.modeling.command 2 | 3 | import io.mockk.mockk 4 | import me.ahoo.wow.api.command.CommandMessage 5 | import me.ahoo.wow.command.SimpleServerCommandExchange 6 | import org.hamcrest.MatcherAssert.* 7 | import org.hamcrest.Matchers.* 8 | import org.junit.jupiter.api.Test 9 | 10 | class ExchangeCommandAggregateKtTest { 11 | 12 | @Test 13 | fun setCommandAggregate() { 14 | val exchange = SimpleServerCommandExchange(mockk>()) 15 | assertThat(exchange.setCommandAggregate(mockk()).getCommandAggregate(), notNullValue()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/saga/stateless/ExchangeCommandStreamKtTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.saga.stateless 2 | 3 | import io.mockk.mockk 4 | import me.ahoo.wow.api.event.DomainEvent 5 | import me.ahoo.wow.event.SimpleDomainEventExchange 6 | import org.hamcrest.MatcherAssert.* 7 | import org.hamcrest.Matchers.* 8 | import org.junit.jupiter.api.Test 9 | 10 | class ExchangeCommandStreamKtTest { 11 | 12 | @Test 13 | fun setCommandStream() { 14 | val exchange = SimpleDomainEventExchange(mockk>()) 15 | assertThat(exchange.setCommandStream(mockk()).getCommandStream(), notNullValue()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wow-core/src/test/kotlin/me/ahoo/wow/sharding/SingleAggregateIdShardingTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.sharding 2 | 3 | import me.ahoo.wow.modeling.aggregateId 4 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 5 | import org.hamcrest.MatcherAssert.* 6 | import org.hamcrest.Matchers.* 7 | import org.junit.jupiter.api.Test 8 | 9 | class SingleAggregateIdShardingTest { 10 | 11 | @Test 12 | fun sharding() { 13 | val sharding = SingleAggregateIdSharding("test") 14 | val actual = sharding.sharding(MOCK_AGGREGATE_METADATA.aggregateId()) 15 | assertThat(actual, equalTo("test")) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wow-core/src/test/resources/META-INF/services/me.ahoo.wow.event.upgrader.EventUpgrader: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | me.ahoo.wow.event.upgrader.MockEventToDroppedUpgrader 14 | me.ahoo.wow.event.upgrader.MockEventChangeRevisionUpgrader -------------------------------------------------------------------------------- /wow-core/src/test/resources/META-INF/services/me.ahoo.wow.exception.ErrorConverterFactory: -------------------------------------------------------------------------------- 1 | me.ahoo.wow.exception.CustomExceptionErrorConverterFactory -------------------------------------------------------------------------------- /wow-core/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | junit.jupiter.testinstance.lifecycle.default = per_class 15 | 16 | -------------------------------------------------------------------------------- /wow-elasticsearch/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | api(project(":wow-query")) 4 | api("org.springframework.data:spring-data-elasticsearch") 5 | testImplementation(project(":wow-tck")) 6 | testImplementation("org.testcontainers:testcontainers") 7 | testImplementation("org.testcontainers:junit-jupiter") 8 | testImplementation("org.testcontainers:elasticsearch") 9 | testImplementation("org.springframework:spring-webflux") 10 | testImplementation("io.projectreactor.netty:reactor-netty-http") 11 | } 12 | -------------------------------------------------------------------------------- /wow-kafka/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | api("io.projectreactor.kafka:reactor-kafka") 4 | implementation("me.ahoo.cosid:cosid-core") 5 | testImplementation("me.ahoo.cosid:cosid-test") 6 | testImplementation(project(":wow-tck")) 7 | testImplementation("org.testcontainers:testcontainers") 8 | testImplementation("org.testcontainers:junit-jupiter") 9 | testImplementation("org.testcontainers:kafka") 10 | } 11 | -------------------------------------------------------------------------------- /wow-kafka/src/test/kotlin/me/ahoo/wow/kafka/DefaultCommandTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.kafka 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultCommandTopicConverterTest { 9 | 10 | @Test 11 | fun convert() { 12 | val topic = DefaultCommandTopicConverter().convert(MOCK_AGGREGATE_METADATA) 13 | assertThat(topic, equalTo("wow.tck.mock_aggregate.command")) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-kafka/src/test/kotlin/me/ahoo/wow/kafka/DefaultEventStreamTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.kafka 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultEventStreamTopicConverterTest { 9 | 10 | @Test 11 | fun convert() { 12 | val topic = DefaultEventStreamTopicConverter().convert(MOCK_AGGREGATE_METADATA) 13 | assertThat(topic, equalTo("wow.tck.mock_aggregate.event")) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-kafka/src/test/kotlin/me/ahoo/wow/kafka/DefaultStateEventTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.kafka 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultStateEventTopicConverterTest { 9 | 10 | @Test 11 | fun convert() { 12 | val topic = DefaultStateEventTopicConverter().convert(MOCK_AGGREGATE_METADATA) 13 | assertThat(topic, equalTo("wow.tck.mock_aggregate.state")) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-models/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.ksp) 3 | } 4 | dependencies { 5 | api(platform(project(":wow-dependencies"))) 6 | api("io.swagger.core.v3:swagger-core-jakarta") 7 | implementation(project(":wow-api")) 8 | implementation("com.fasterxml.jackson.core:jackson-annotations") 9 | api("jakarta.validation:jakarta.validation-api") 10 | api("io.projectreactor:reactor-core") 11 | api("io.projectreactor.kotlin:reactor-kotlin-extensions") 12 | ksp(project(":wow-compiler")) 13 | testImplementation(project(":wow-test")) 14 | testImplementation("io.projectreactor:reactor-test") 15 | } 16 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/CompletedCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.models.common 15 | 16 | interface CompletedCapable { 17 | val completed: Boolean 18 | } 19 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/ItemIdCapable.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import jakarta.validation.constraints.NotBlank 4 | 5 | interface ItemIdCapable { 6 | val itemId: String 7 | } 8 | 9 | interface NotBlankItemIdCapable : ItemIdCapable { 10 | @get:NotBlank 11 | override val itemId: String 12 | } 13 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/NotBlankNameCapable.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import jakarta.validation.constraints.NotBlank 4 | import me.ahoo.wow.api.naming.Named 5 | 6 | interface NotBlankNameCapable : Named { 7 | @get:NotBlank 8 | override val name: String 9 | } 10 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/QuantityCapable.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | interface NullableQuantityCapable { 4 | val qty: Int? 5 | } 6 | 7 | interface QuantityCapable : NullableQuantityCapable { 8 | override val qty: Int 9 | } 10 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/ReasonCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.models.common 15 | 16 | interface ReasonCapable { 17 | val reason: String 18 | } 19 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/RemarkCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.models.common 15 | 16 | interface RemarkCapable { 17 | val remark: String 18 | } 19 | -------------------------------------------------------------------------------- /wow-models/src/main/kotlin/me/ahoo/wow/models/common/TypeCapable.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema 4 | import jakarta.validation.constraints.NotBlank 5 | 6 | interface TypeCapable { 7 | val type: String 8 | 9 | companion object { 10 | const val TYPE = "type" 11 | } 12 | } 13 | 14 | interface NotBlankTypeCapable : TypeCapable { 15 | @get:NotBlank 16 | override val type: String 17 | } 18 | 19 | interface PolymorphicTypeCapable : NotBlankTypeCapable { 20 | @get:Schema(accessMode = Schema.AccessMode.READ_WRITE) 21 | override val type: String 22 | } 23 | -------------------------------------------------------------------------------- /wow-models/src/test/kotlin/me/ahoo/wow/models/common/CompletedCapableTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class CompletedCapableTest { 7 | 8 | @Test 9 | fun `test completed property`() { 10 | val completedCapable = object : CompletedCapable { 11 | override val completed: Boolean = true 12 | } 13 | completedCapable.completed.assert().isTrue() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-models/src/test/kotlin/me/ahoo/wow/models/common/ItemIdCapableTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class ItemIdCapableTest { 7 | 8 | @Test 9 | fun `test itemId property`() { 10 | val itemIdCapable = object : ItemIdCapable { 11 | override val itemId: String = "This is a test itemId." 12 | } 13 | itemIdCapable.itemId.assert().isEqualTo("This is a test itemId.") 14 | } 15 | 16 | @Test 17 | fun `test NotBlankItemIdCapable`() { 18 | val notBlankItemIdCapable = object : NotBlankItemIdCapable { 19 | override val itemId: String = "This is a test itemId." 20 | } 21 | notBlankItemIdCapable.itemId.assert().isEqualTo("This is a test itemId.") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /wow-models/src/test/kotlin/me/ahoo/wow/models/common/QuantityCapableTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class QuantityCapableTest { 7 | 8 | @Test 9 | fun `test qty property`() { 10 | val quantityCapable = object : QuantityCapable { 11 | override val qty: Int = 10 12 | } 13 | quantityCapable.qty.assert().isEqualTo(10) 14 | } 15 | 16 | @Test 17 | fun `test NullableQuantityCapable`() { 18 | val quantityCapable = object : NullableQuantityCapable { 19 | override val qty: Int? = null 20 | } 21 | quantityCapable.qty.assert().isNull() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /wow-models/src/test/kotlin/me/ahoo/wow/models/common/ReasonCapableTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class ReasonCapableTest { 7 | 8 | @Test 9 | fun `test reason property`() { 10 | val reasonCapable = object : ReasonCapable { 11 | override val reason: String = "This is a test reason." 12 | } 13 | reasonCapable.reason.assert().isEqualTo("This is a test reason.") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-models/src/test/kotlin/me/ahoo/wow/models/common/RemarkCapableTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.models.common 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class RemarkCapableTest { 7 | 8 | @Test 9 | fun `test remark property`() { 10 | val remarkCapable = object : RemarkCapable { 11 | override val remark: String = "This is a test remark." 12 | } 13 | remarkCapable.remark.assert().isEqualTo("This is a test remark.") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-mongo/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | api(project(":wow-query")) 4 | api("org.mongodb:mongodb-driver-reactivestreams") 5 | implementation("com.fasterxml.jackson.core:jackson-annotations") 6 | implementation("com.google.guava:guava") 7 | testImplementation(project(":wow-tck")) 8 | testImplementation("org.testcontainers:testcontainers") 9 | testImplementation("org.testcontainers:junit-jupiter") 10 | testImplementation("org.testcontainers:mongodb") 11 | } 12 | -------------------------------------------------------------------------------- /wow-openapi/build.gradle.kts: -------------------------------------------------------------------------------- 1 | description = "Wow OpenAPI Specification" 2 | 3 | dependencies { 4 | api(project(":wow-core")) 5 | api(project(":wow-query")) 6 | api(project(":wow-schema")) 7 | implementation(project(":wow-bi")) 8 | implementation(kotlin("reflect")) 9 | implementation("org.springframework:spring-web") 10 | api("io.swagger.core.v3:swagger-core-jakarta") 11 | testImplementation(project(":wow-models")) 12 | testImplementation(project(":example-domain")) 13 | testImplementation(project(":example-transfer-domain")) 14 | testImplementation(project(":wow-tck")) 15 | } 16 | -------------------------------------------------------------------------------- /wow-openapi/src/main/resources/META-INF/services/io.swagger.v3.core.converter.ModelConverter: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | me.ahoo.wow.openapi.converter.BoundedContextSchemaNameConverter 15 | me.ahoo.wow.openapi.converter.WowSchemaConverter 16 | -------------------------------------------------------------------------------- /wow-openapi/src/main/resources/META-INF/services/me.ahoo.wow.openapi.global.GlobalRouteSpecFactory: -------------------------------------------------------------------------------- 1 | me.ahoo.wow.openapi.global.CommandWaitRouteSpecFactory 2 | me.ahoo.wow.openapi.aggregate.command.CommandFacadeRouteSpecFactory 3 | me.ahoo.wow.openapi.global.GetWowMetadataRouteSpecFactory 4 | me.ahoo.wow.openapi.global.GenerateGlobalIdRouteSpecFactory 5 | me.ahoo.wow.openapi.global.GenerateBIScriptRouteSpecFactory -------------------------------------------------------------------------------- /wow-openapi/src/main/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts": { 3 | "wow.openapi": { 4 | "alias": "wow.openapi", 5 | "scopes": [ 6 | "me.ahoo.wow.openapi" 7 | ] 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /wow-openapi/src/test/kotlin/me/ahoo/wow/openapi/BatchResultTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.openapi 2 | 3 | import me.ahoo.test.asserts.assert 4 | import org.junit.jupiter.api.Test 5 | 6 | class BatchResultTest { 7 | @Test 8 | fun test() { 9 | val batchResult = BatchResult("cursorId", 1) 10 | batchResult.afterId.assert().isEqualTo("cursorId") 11 | batchResult.size.assert().isEqualTo(1) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /wow-openapi/src/test/kotlin/me/ahoo/wow/openapi/RouterSpecsTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.openapi 2 | 3 | import io.swagger.v3.oas.models.OpenAPI 4 | import me.ahoo.test.asserts.assert 5 | import me.ahoo.wow.naming.MaterializedNamedBoundedContext 6 | import org.junit.jupiter.api.Test 7 | 8 | class RouterSpecsTest { 9 | @Test 10 | fun build() { 11 | val routerSpecs = RouterSpecs(MaterializedNamedBoundedContext("test")).build() 12 | routerSpecs.assert().isNotEmpty() 13 | } 14 | 15 | @Test 16 | fun mergeOpenAPI() { 17 | val openAPI = OpenAPI() 18 | RouterSpecs(MaterializedNamedBoundedContext("test")).build() 19 | .mergeOpenAPI(openAPI) 20 | openAPI.components.schemas.assert().isNotEmpty() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wow-openapi/src/test/kotlin/me/ahoo/wow/openapi/TagsTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.openapi 2 | 3 | import io.swagger.v3.oas.annotations.tags.Tag 4 | import me.ahoo.test.asserts.assert 5 | import me.ahoo.wow.openapi.Tags.toTags 6 | import org.junit.jupiter.api.Test 7 | 8 | class TagsTest { 9 | 10 | @Test 11 | fun singleToTags() { 12 | val tags = SingleTag::class.java.toTags() 13 | tags.map { it.name }.assert().contains("test") 14 | } 15 | 16 | @Test 17 | fun multiToTags() { 18 | val tags = MultiTag::class.java.toTags() 19 | tags.map { it.name }.assert().contains("test", "test2") 20 | } 21 | } 22 | 23 | @Tag(name = "test") 24 | @Tag(name = "test2") 25 | interface MultiTag 26 | 27 | @Tag(name = "test") 28 | interface SingleTag 29 | -------------------------------------------------------------------------------- /wow-opentelemetry/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api") 4 | testImplementation(project(":wow-tck")) 5 | testImplementation("io.projectreactor:reactor-test") 6 | testImplementation("io.opentelemetry:opentelemetry-sdk") 7 | } 8 | -------------------------------------------------------------------------------- /wow-opentelemetry/src/test/kotlin/me/ahoo/wow/opentelemetry/eventsourcing/TracingEventStoreTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.opentelemetry.eventsourcing 2 | 3 | import me.ahoo.wow.eventsourcing.EventStore 4 | import me.ahoo.wow.eventsourcing.InMemoryEventStore 5 | import me.ahoo.wow.opentelemetry.Tracing.tracing 6 | import me.ahoo.wow.tck.eventsourcing.EventStoreSpec 7 | 8 | class TracingEventStoreTest : EventStoreSpec() { 9 | override fun createEventStore(): EventStore { 10 | return InMemoryEventStore().tracing() 11 | } 12 | 13 | override fun loadEventStreamGivenWrongVersion() = Unit 14 | } 15 | -------------------------------------------------------------------------------- /wow-opentelemetry/src/test/kotlin/me/ahoo/wow/opentelemetry/messaging/TracingLocalCommandBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.opentelemetry.messaging 2 | 3 | import me.ahoo.wow.command.CommandBus 4 | import me.ahoo.wow.command.InMemoryCommandBus 5 | import me.ahoo.wow.opentelemetry.Tracing.tracing 6 | import me.ahoo.wow.tck.command.CommandBusSpec 7 | 8 | class TracingLocalCommandBusTest : CommandBusSpec() { 9 | override fun createMessageBus(): CommandBus { 10 | return InMemoryCommandBus().tracing() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wow-opentelemetry/src/test/kotlin/me/ahoo/wow/opentelemetry/messaging/TracingLocalEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.opentelemetry.messaging 2 | 3 | import me.ahoo.wow.event.DomainEventBus 4 | import me.ahoo.wow.event.InMemoryDomainEventBus 5 | import me.ahoo.wow.opentelemetry.Tracing.tracing 6 | import me.ahoo.wow.tck.event.DomainEventBusSpec 7 | 8 | class TracingLocalEventBusTest : DomainEventBusSpec() { 9 | override fun createMessageBus(): DomainEventBus { 10 | return InMemoryDomainEventBus().tracing() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wow-opentelemetry/src/test/kotlin/me/ahoo/wow/opentelemetry/messaging/TracingLocalStateEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.opentelemetry.messaging 2 | 3 | import me.ahoo.wow.eventsourcing.state.InMemoryStateEventBus 4 | import me.ahoo.wow.eventsourcing.state.StateEventBus 5 | import me.ahoo.wow.opentelemetry.Tracing.tracing 6 | import me.ahoo.wow.tck.eventsourcing.state.StateEventBusSpec 7 | 8 | class TracingLocalStateEventBusTest : StateEventBusSpec() { 9 | override fun createMessageBus(): StateEventBus { 10 | return InMemoryStateEventBus().tracing() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wow-opentelemetry/src/test/kotlin/me/ahoo/wow/opentelemetry/snapshot/TracingSnapshotRepositoryTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.opentelemetry.snapshot 2 | 3 | import me.ahoo.wow.eventsourcing.snapshot.InMemorySnapshotRepository 4 | import me.ahoo.wow.eventsourcing.snapshot.SnapshotRepository 5 | import me.ahoo.wow.opentelemetry.Tracing.tracing 6 | import me.ahoo.wow.tck.eventsourcing.snapshot.SnapshotRepositorySpec 7 | 8 | class TracingSnapshotRepositoryTest : SnapshotRepositorySpec() { 9 | override fun createSnapshotRepository(): SnapshotRepository { 10 | return InMemorySnapshotRepository().tracing() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wow-query/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api("io.projectreactor:reactor-core") 3 | api(project(":wow-core")) 4 | api("io.projectreactor:reactor-test") 5 | testImplementation(project(":wow-tck")) 6 | } -------------------------------------------------------------------------------- /wow-query/src/test/resources/and.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "condition": { 3 | "field": "", 4 | "operator": "AND", 5 | "children": [ 6 | { 7 | "field": "_id", 8 | "operator": "EQ", 9 | "value": "0TyzPmFV003j001" 10 | } 11 | ] 12 | }, 13 | "sort": [], 14 | "limit": 0 15 | } -------------------------------------------------------------------------------- /wow-query/src/test/resources/empty.pagination.json: -------------------------------------------------------------------------------- 1 | { 2 | "condition": { 3 | "field": "", 4 | "operator": "EMPTY" 5 | }, 6 | "sort": [], 7 | "pagination": { 8 | "index": 0, 9 | "size": 10 10 | } 11 | } -------------------------------------------------------------------------------- /wow-r2dbc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | implementation("io.netty:netty-all") 4 | implementation("me.ahoo.cosid:cosid-core") 5 | api("io.r2dbc:r2dbc-spi") 6 | api("io.r2dbc:r2dbc-pool") 7 | api("io.r2dbc:r2dbc-proxy") 8 | testImplementation(project(":wow-tck")) 9 | testImplementation("me.ahoo.cosid:cosid-test") 10 | testImplementation("org.mariadb:r2dbc-mariadb") 11 | testImplementation("org.testcontainers:mariadb") 12 | testImplementation("org.testcontainers:r2dbc") 13 | testImplementation("org.mariadb.jdbc:mariadb-java-client") 14 | } 15 | -------------------------------------------------------------------------------- /wow-redis/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | api("org.springframework.data:spring-data-redis") 4 | implementation("io.lettuce:lettuce-core") 5 | testImplementation(project(":wow-tck")) 6 | } 7 | -------------------------------------------------------------------------------- /wow-redis/src/main/resources/prepare_prepare.lua: -------------------------------------------------------------------------------- 1 | -- Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled. 2 | redis.replicate_commands(); 3 | 4 | local key = KEYS[1]; 5 | 6 | local currentAt = tonumber(ARGV[1]); 7 | local ttlAt = ARGV[2]; 8 | local value = ARGV[3]; 9 | 10 | local ttlAtField = "ttlAt"; 11 | local valueField = "value"; 12 | local prepareKey = "prepare:" .. key; 13 | 14 | local function getCurrentTtlAt() 15 | local currentTtlAt = redis.call("HGET", prepareKey, ttlAtField); 16 | if currentTtlAt then 17 | return tonumber(currentTtlAt); 18 | end 19 | return 0; 20 | end 21 | 22 | if getCurrentTtlAt() > currentAt then 23 | return false; 24 | end 25 | 26 | redis.call("HSET", prepareKey, ttlAtField, ttlAt, valueField, value); 27 | 28 | return true; -------------------------------------------------------------------------------- /wow-redis/src/main/resources/prepare_reprepare.lua: -------------------------------------------------------------------------------- 1 | -- Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled. 2 | redis.replicate_commands(); 3 | 4 | local key = KEYS[1]; 5 | 6 | local ttlAt = ARGV[1]; 7 | local value = ARGV[2]; 8 | 9 | local ttlAtField = "ttlAt"; 10 | local valueField = "value"; 11 | local prepareKey = "prepare:" .. key; 12 | 13 | local currentTtlAt = redis.call("HGET", prepareKey, ttlAtField); 14 | 15 | if currentTtlAt == nil then 16 | return false; 17 | end 18 | 19 | redis.call("HSET", prepareKey, ttlAtField, ttlAt, valueField, value); 20 | 21 | return true; -------------------------------------------------------------------------------- /wow-redis/src/main/resources/prepare_reprepare_with_old_value.lua: -------------------------------------------------------------------------------- 1 | -- Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled. 2 | redis.replicate_commands(); 3 | 4 | local key = KEYS[1]; 5 | 6 | local ttlAt = ARGV[1]; 7 | local value = ARGV[2]; 8 | local oldValue = ARGV[3]; 9 | 10 | local ttlAtField = "ttlAt"; 11 | local valueField = "value"; 12 | local prepareKey = "prepare:" .. key; 13 | 14 | local currentValue = redis.call("HGET", prepareKey, valueField); 15 | 16 | if currentValue ~= oldValue then 17 | return false; 18 | end 19 | 20 | redis.call("HSET", prepareKey, ttlAtField, ttlAt, valueField, value); 21 | 22 | return true; -------------------------------------------------------------------------------- /wow-redis/src/main/resources/prepare_rollback.lua: -------------------------------------------------------------------------------- 1 | -- Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled. 2 | redis.replicate_commands(); 3 | 4 | local key = KEYS[1]; 5 | 6 | local currentAt = tonumber(ARGV[1]); 7 | 8 | local ttlAtField = "ttlAt"; 9 | local prepareKey = "prepare:" .. key; 10 | 11 | local function getCurrentTtlAt() 12 | local currentTtlAt = redis.call("HGET", prepareKey, ttlAtField); 13 | if currentTtlAt then 14 | return tonumber(currentTtlAt); 15 | end 16 | return 0; 17 | end 18 | 19 | if getCurrentTtlAt() < currentAt then 20 | return false; 21 | end 22 | 23 | local result = redis.call("DEL", prepareKey); 24 | 25 | if result > 0 then 26 | return true 27 | end 28 | 29 | return false -------------------------------------------------------------------------------- /wow-redis/src/main/resources/prepare_rollback_with_old_value.lua: -------------------------------------------------------------------------------- 1 | -- Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled. 2 | redis.replicate_commands(); 3 | 4 | local key = KEYS[1]; 5 | 6 | local oldValue = ARGV[1]; 7 | 8 | local valueField = "value"; 9 | local prepareKey = "prepare:" .. key; 10 | 11 | local currentValue = redis.call("HGET", prepareKey, valueField); 12 | 13 | if currentValue == nil or currentValue ~= oldValue then 14 | return false; 15 | end 16 | 17 | local result = redis.call("DEL", prepareKey); 18 | 19 | if result > 0 then 20 | return true 21 | end 22 | 23 | return false -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/DefaultCommandTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultCommandTopicConverterTest { 9 | 10 | @Test 11 | fun convert() { 12 | val actual = DefaultCommandTopicConverter.convert(MOCK_AGGREGATE_METADATA) 13 | assertThat(actual, equalTo("tck.mock_aggregate:command")) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/DefaultEventStreamTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultEventStreamTopicConverterTest { 9 | @Test 10 | fun convert() { 11 | val actual = DefaultEventStreamTopicConverter.convert(MOCK_AGGREGATE_METADATA) 12 | assertThat(actual, equalTo("tck.mock_aggregate:event")) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/DefaultStateEventTopicConverterTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.tck.mock.MOCK_AGGREGATE_METADATA 4 | import org.hamcrest.MatcherAssert.* 5 | import org.hamcrest.Matchers.* 6 | import org.junit.jupiter.api.Test 7 | 8 | class DefaultStateEventTopicConverterTest { 9 | 10 | @Test 11 | fun convert() { 12 | val actual = DefaultStateEventTopicConverter.convert(MOCK_AGGREGATE_METADATA) 13 | assertThat(actual, equalTo("tck.mock_aggregate:state")) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/RedisCommandBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.command.CommandBus 4 | import me.ahoo.wow.redis.RedisInitializer 5 | import me.ahoo.wow.tck.command.CommandBusSpec 6 | import org.junit.jupiter.api.BeforeEach 7 | 8 | class RedisCommandBusTest : CommandBusSpec() { 9 | protected lateinit var redisInitializer: RedisInitializer 10 | 11 | @BeforeEach 12 | fun setup() { 13 | redisInitializer = RedisInitializer() 14 | } 15 | 16 | override fun createMessageBus(): CommandBus { 17 | return RedisCommandBus(redisInitializer.redisTemplate) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/RedisDomainEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.event.DomainEventBus 4 | import me.ahoo.wow.redis.RedisInitializer 5 | import me.ahoo.wow.tck.event.DomainEventBusSpec 6 | import org.junit.jupiter.api.BeforeEach 7 | 8 | class RedisDomainEventBusTest : DomainEventBusSpec() { 9 | protected lateinit var redisInitializer: RedisInitializer 10 | 11 | @BeforeEach 12 | fun setup() { 13 | redisInitializer = RedisInitializer() 14 | } 15 | 16 | override fun createMessageBus(): DomainEventBus { 17 | return RedisDomainEventBus(redisInitializer.redisTemplate) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/bus/RedisStateEventBusTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.bus 2 | 3 | import me.ahoo.wow.eventsourcing.state.StateEventBus 4 | import me.ahoo.wow.redis.RedisInitializer 5 | import me.ahoo.wow.tck.eventsourcing.state.StateEventBusSpec 6 | import org.junit.jupiter.api.BeforeEach 7 | 8 | class RedisStateEventBusTest : StateEventBusSpec() { 9 | protected lateinit var redisInitializer: RedisInitializer 10 | 11 | @BeforeEach 12 | fun setup() { 13 | redisInitializer = RedisInitializer() 14 | } 15 | 16 | override fun createMessageBus(): StateEventBus { 17 | return RedisStateEventBus(redisInitializer.redisTemplate) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wow-redis/src/test/kotlin/me/ahoo/wow/redis/prepare/RedisPrepareKeySpec.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.redis.prepare 2 | 3 | import me.ahoo.wow.infra.prepare.PrepareKeyFactory 4 | import me.ahoo.wow.redis.RedisInitializer 5 | import me.ahoo.wow.tck.prepare.PrepareKeySpec 6 | import org.junit.jupiter.api.BeforeEach 7 | 8 | abstract class RedisPrepareKeySpec : PrepareKeySpec() { 9 | protected lateinit var redisInitializer: RedisInitializer 10 | 11 | @BeforeEach 12 | override fun setup() { 13 | redisInitializer = RedisInitializer() 14 | super.setup() 15 | } 16 | 17 | override fun createPrepareKeyFactory(): PrepareKeyFactory { 18 | return RedisPrepareKeyFactory(redisInitializer.redisTemplate) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wow-schema/src/main/kotlin/me/ahoo/wow/schema/openapi/InlineSchemaCapable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.schema.openapi 15 | 16 | interface InlineSchemaCapable { 17 | val inline: Boolean 18 | } 19 | -------------------------------------------------------------------------------- /wow-schema/src/main/kotlin/me/ahoo/wow/schema/typed/AggregatedFields.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.schema.typed 15 | 16 | interface AggregatedFields 17 | -------------------------------------------------------------------------------- /wow-schema/src/main/kotlin/me/ahoo/wow/schema/typed/query/AggregatedListQuery.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.schema.typed.query 15 | 16 | interface AggregatedListQuery 17 | -------------------------------------------------------------------------------- /wow-schema/src/main/kotlin/me/ahoo/wow/schema/typed/query/AggregatedPagedQuery.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.schema.typed.query 15 | 16 | interface AggregatedPagedQuery 17 | -------------------------------------------------------------------------------- /wow-schema/src/main/kotlin/me/ahoo/wow/schema/typed/query/AggregatedSingleQuery.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright [2021-present] [ahoo wang (https://github.com/Ahoo-Wang)]. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | package me.ahoo.wow.schema.typed.query 15 | 16 | interface AggregatedSingleQuery 17 | -------------------------------------------------------------------------------- /wow-schema/src/main/resources/META-INF/wow-schema/AggregateId.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "type": "object", 4 | "properties": { 5 | "contextName": { 6 | "type": "string", 7 | "minLength": 1, 8 | "description": "aggregate context name" 9 | }, 10 | "aggregateName": { 11 | "type": "string", 12 | "minLength": 1, 13 | "description": "aggregate name" 14 | }, 15 | "tenantId": { 16 | "type": "string", 17 | "minLength": 1, 18 | "description": "aggregate tenant id", 19 | "default": "(0)" 20 | }, 21 | "aggregateId": { 22 | "type": "string", 23 | "minLength": 1, 24 | "description": "aggregate id" 25 | } 26 | }, 27 | "required": [ 28 | "contextName", 29 | "aggregateName", 30 | "tenantId", 31 | "aggregateId" 32 | ] 33 | } -------------------------------------------------------------------------------- /wow-schema/src/main/resources/META-INF/wow-schema/CurrencyUnit.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "type": "string", 4 | "format": "currency", 5 | "default": "CNY", 6 | "examples": [ 7 | "CNY", 8 | "USD", 9 | "EUR" 10 | ] 11 | } -------------------------------------------------------------------------------- /wow-schema/src/main/resources/META-INF/wow-schema/Money.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "type": "object", 4 | "properties": { 5 | "currency": { 6 | "type": "string", 7 | "format": "currency", 8 | "default": "CNY", 9 | "examples": [ 10 | "CNY", 11 | "USD", 12 | "EUR" 13 | ] 14 | }, 15 | "amount": { 16 | "type": "number" 17 | } 18 | }, 19 | "required": [ 20 | "currency", 21 | "amount" 22 | ] 23 | } -------------------------------------------------------------------------------- /wow-schema/src/test/kotlin/me/ahoo/wow/schema/WowSchemaLoaderTest.kt: -------------------------------------------------------------------------------- 1 | package me.ahoo.wow.schema 2 | 3 | import me.ahoo.test.asserts.assertThrownBy 4 | import org.junit.jupiter.api.Test 5 | 6 | class WowSchemaLoaderTest { 7 | 8 | @Test 9 | fun loadAsStringNotFound() { 10 | val resourceName = "not_found.json" 11 | assertThrownBy { 12 | WowSchemaLoader.loadAsString(resourceName) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-schema/src/test/resources/META-INF/wow-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "contexts": { 3 | "wow-schema": { 4 | "alias": "wow.schema", 5 | "scopes": [ 6 | "me.ahoo.wow.schema" 7 | ], 8 | "aggregates": { 9 | "mock_empty_aggregate": { 10 | "type": "me.ahoo.wow.schema.MockEmptyAggregate" 11 | } 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wow-schema/src/test/resources/META-INF/wow-schema/OrderAggregatedFields.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema" : "https://json-schema.org/draft/2020-12/schema", 3 | "type" : "string", 4 | "enum" : [ "", "aggregateId", "tenantId", "ownerId", "version", "eventId", "firstOperator", "operator", "firstEventTime", "eventTime", "deleted", "state", "state.address", "state.address.city", "state.address.country", "state.address.detail", "state.address.district", "state.address.province", "state.id", "state.items", "state.items.id", "state.items.price", "state.items.productId", "state.items.quantity", "state.items.totalPrice", "state.paidAmount", "state.payable", "state.status", "state.totalAmount" ] 5 | } -------------------------------------------------------------------------------- /wow-spring/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | implementation(project(":wow-query")) 4 | api("org.springframework:spring-context") 5 | } 6 | -------------------------------------------------------------------------------- /wow-webflux/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":wow-core")) 3 | api(project(":wow-openapi")) 4 | implementation(project(":wow-bi")) 5 | implementation("org.springframework:spring-context") 6 | implementation("org.springframework:spring-webflux") 7 | testImplementation("org.springframework:spring-test") 8 | testImplementation(project(":wow-tck")) 9 | testImplementation(project(":example-domain")) 10 | } 11 | -------------------------------------------------------------------------------- /wow-webflux/src/main/resources/META-INF/services/me.ahoo.wow.exception.ErrorConverterFactory: -------------------------------------------------------------------------------- 1 | me.ahoo.wow.webflux.exception.HandlerMethodValidationExceptionConverterFactory 2 | me.ahoo.wow.webflux.exception.NoResourceFoundExceptionConverterFactory 3 | me.ahoo.wow.webflux.exception.ServerWebInputExceptionConverterFactory --------------------------------------------------------------------------------