completely implementation about cqrs and event sourcing
But not testing yet And not yet for rest too for query
This commit is contained in:
parent
05431bd77b
commit
d3e8d63287
@ -0,0 +1,46 @@
|
||||
package com.cubetiqs.demo.axon.api
|
||||
|
||||
import com.cubetiqs.demo.axon.dto.AccountCreationDTO
|
||||
import com.cubetiqs.demo.axon.dto.MoneyAmountDTO
|
||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||
import com.cubetiqs.demo.axon.service.AccountCommandService
|
||||
import io.swagger.annotations.Api
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.ResponseStatus
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = ["/accounts"])
|
||||
@Api(value = "Bank Account Commands", description = "Bank Account Commands API")
|
||||
class AccountCommandController @Autowired constructor(
|
||||
private val accountCommandService: AccountCommandService
|
||||
) {
|
||||
@PostMapping
|
||||
@ResponseStatus(value = HttpStatus.CREATED)
|
||||
fun createAccount(@RequestBody creationDTO: AccountCreationDTO): CompletableFuture<BankAccount?> {
|
||||
return this.accountCommandService.createAccount(creationDTO)
|
||||
}
|
||||
|
||||
@PutMapping(value = ["/credit/{accountId}"])
|
||||
fun creditMoneyToAccount(
|
||||
@PathVariable(value = "accountId") accountId: String,
|
||||
@RequestBody moneyCreditDTO: MoneyAmountDTO
|
||||
): CompletableFuture<String?> {
|
||||
return this.accountCommandService.creditMoneyToAccount(accountId, moneyCreditDTO)
|
||||
}
|
||||
|
||||
@PutMapping(value = ["/debit/{accountId}"])
|
||||
fun debitMoneyFromAccount(
|
||||
@PathVariable(value = "accountId") accountId: String,
|
||||
@RequestBody moneyDebitDTO: MoneyAmountDTO
|
||||
): CompletableFuture<String?>? {
|
||||
return this.accountCommandService.debitMoneyFromAccount(accountId, moneyDebitDTO)
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.cubetiqs.demo.axon.api
|
||||
|
||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
class AccountQueryController {
|
||||
@GetMapping("/{accountId}")
|
||||
fun findById(@PathVariable("accountId") accountId: String?): CompletableFuture<BankAccount?>? {
|
||||
return this.accountQueryService.findById(accountId)
|
||||
}
|
||||
|
||||
@GetMapping("/{accountId}/events")
|
||||
fun listEventsForAccount(@PathVariable(value = "accountId") accountId: String?): List<Any?>? {
|
||||
return this.accountQueryService.listEventsForAccount(accountId)
|
||||
}
|
||||
}
|
@ -5,8 +5,10 @@ import com.cubetiqs.demo.axon.event.AccountCreatedEvent
|
||||
import com.cubetiqs.demo.axon.event.MoneyCreditedEvent
|
||||
import com.cubetiqs.demo.axon.event.MoneyDebitedEvent
|
||||
import com.cubetiqs.demo.axon.exception.AccountNotFoundException
|
||||
import com.cubetiqs.demo.axon.query.FindBankAccountQuery
|
||||
import com.cubetiqs.demo.axon.repository.BankAccountRepository
|
||||
import org.axonframework.eventhandling.EventHandler
|
||||
import org.axonframework.queryhandling.QueryHandler
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Component
|
||||
@ -56,4 +58,10 @@ class BankAccountProjection @Autowired constructor(
|
||||
throw AccountNotFoundException(event.accountId)
|
||||
}
|
||||
}
|
||||
|
||||
@QueryHandler
|
||||
fun handle(query: FindBankAccountQuery): BankAccount? {
|
||||
log.debug("Handling FindBankAccountQuery query: {}", query)
|
||||
return this.bankAccountRepository.findById(query.accountId).orElse(null)
|
||||
}
|
||||
}
|
@ -3,5 +3,5 @@ package com.cubetiqs.demo.axon.query
|
||||
import java.util.UUID
|
||||
|
||||
data class FindBankAccountQuery(
|
||||
val id: UUID
|
||||
val accountId: UUID
|
||||
)
|
@ -6,6 +6,7 @@ import com.cubetiqs.demo.axon.command.DebitMoneyCommand
|
||||
import com.cubetiqs.demo.axon.dto.AccountCreationDTO
|
||||
import com.cubetiqs.demo.axon.dto.MoneyAmountDTO
|
||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||
import com.cubetiqs.demo.axon.util.text.formatUuid
|
||||
import org.axonframework.commandhandling.gateway.CommandGateway
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Service
|
||||
@ -29,7 +30,7 @@ class AccountCommandServiceImpl @Autowired constructor(
|
||||
override fun creditMoneyToAccount(accountId: String?, moneyCreditDTO: MoneyAmountDTO): CompletableFuture<String?> {
|
||||
return commandGateway.send(
|
||||
CreditMoneyCommand(
|
||||
formatUuid(accountId),
|
||||
accountId.formatUuid(),
|
||||
moneyCreditDTO.amount
|
||||
)
|
||||
)
|
||||
@ -38,13 +39,11 @@ class AccountCommandServiceImpl @Autowired constructor(
|
||||
override fun debitMoneyFromAccount(accountId: String?, moneyDebitDTO: MoneyAmountDTO): CompletableFuture<String?> {
|
||||
return commandGateway.send(
|
||||
DebitMoneyCommand(
|
||||
formatUuid(accountId),
|
||||
accountId.formatUuid(),
|
||||
moneyDebitDTO.amount
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun formatUuid(accountId: String?): UUID {
|
||||
return UUID.fromString(accountId)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.cubetiqs.demo.axon.service
|
||||
|
||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||
import org.springframework.stereotype.Service
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
@Service
|
||||
interface AccountQueryService {
|
||||
fun findById(accountId: String?): CompletableFuture<BankAccount?>
|
||||
fun listEventsForAccount(accountId: String?): List<Any?>
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.cubetiqs.demo.axon.service
|
||||
|
||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||
import com.cubetiqs.demo.axon.query.FindBankAccountQuery
|
||||
import com.cubetiqs.demo.axon.util.text.formatUuid
|
||||
import org.axonframework.eventsourcing.eventstore.EventStore
|
||||
import org.axonframework.messaging.responsetypes.ResponseTypes
|
||||
import org.axonframework.queryhandling.QueryGateway
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.stereotype.Service
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.stream.Collectors
|
||||
|
||||
@Service
|
||||
class AccountQueryServiceImpl @Autowired constructor(
|
||||
private val queryGateway: QueryGateway,
|
||||
private val eventStore: EventStore
|
||||
) : AccountQueryService {
|
||||
override fun findById(accountId: String?): CompletableFuture<BankAccount?> {
|
||||
return this.queryGateway.query(
|
||||
FindBankAccountQuery(accountId.formatUuid()),
|
||||
ResponseTypes.instanceOf(BankAccount::class.java)
|
||||
)
|
||||
}
|
||||
|
||||
override fun listEventsForAccount(accountId: String?): List<Any?> {
|
||||
return this.eventStore
|
||||
.readEvents(accountId.formatUuid().toString())
|
||||
.asStream()
|
||||
.map { it.payload }
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.cubetiqs.demo.axon.util.text
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
fun String?.formatUuid(): UUID {
|
||||
return UUID.fromString(this)
|
||||
}
|
@ -30,3 +30,7 @@ spring:
|
||||
temp:
|
||||
use_jdbc_metadata_defaults: false
|
||||
open-in-view: true
|
||||
|
||||
axon:
|
||||
serializer:
|
||||
general: jackson
|
Loading…
Reference in New Issue
Block a user