add projection
add dtos Add exception for account add repository add account service command
This commit is contained in:
parent
8e9fd6935f
commit
05431bd77b
@ -1,15 +1,11 @@
|
|||||||
package com.cubetiqs.demo.axon
|
package com.cubetiqs.demo.axon
|
||||||
|
|
||||||
import com.cubetiqs.demo.axon.entity.BankAccount
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
import org.springframework.boot.runApplication
|
import org.springframework.boot.runApplication
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.stereotype.Repository
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
class AxonApplication
|
class AxonApplication
|
||||||
@ -25,7 +21,4 @@ class DefaultController {
|
|||||||
fun index(): ResponseEntity<Any> {
|
fun index(): ResponseEntity<Any> {
|
||||||
return ResponseEntity.ok("ok")
|
return ResponseEntity.ok("ok")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Repository
|
|
||||||
interface BankAccountRepository : JpaRepository<BankAccount, UUID>
|
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.cubetiqs.demo.axon.dto
|
||||||
|
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
data class AccountCreationDTO(
|
||||||
|
var initialBalance: BigDecimal? = null,
|
||||||
|
var owner: String? = null
|
||||||
|
)
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.cubetiqs.demo.axon.dto
|
||||||
|
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
data class MoneyAmountDTO(
|
||||||
|
var amount: BigDecimal? = null
|
||||||
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.demo.axon.exception
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class AccountNotFoundException(id: UUID?) : Throwable("Cannot found account number [$id]")
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.cubetiqs.demo.axon.projection
|
||||||
|
|
||||||
|
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||||
|
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.repository.BankAccountRepository
|
||||||
|
import org.axonframework.eventhandling.EventHandler
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.util.Optional
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class BankAccountProjection @Autowired constructor(
|
||||||
|
private val bankAccountRepository: BankAccountRepository
|
||||||
|
) {
|
||||||
|
private val log = LoggerFactory.getLogger(this.javaClass)
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun on(event: AccountCreatedEvent) {
|
||||||
|
log.debug("Handling a Bank Account creation command {}", event.id)
|
||||||
|
val bankAccount = BankAccount(
|
||||||
|
event.id,
|
||||||
|
event.owner,
|
||||||
|
event.initialBalance
|
||||||
|
)
|
||||||
|
this.bankAccountRepository.save(bankAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
@Throws(AccountNotFoundException::class)
|
||||||
|
fun on(event: MoneyCreditedEvent) {
|
||||||
|
log.debug("Handling an Account Credit command {}", event.accountId)
|
||||||
|
val optionalBankAccount: Optional<BankAccount> = this.bankAccountRepository.findById(event.accountId!!)
|
||||||
|
if (optionalBankAccount.isPresent) {
|
||||||
|
val bankAccount: BankAccount = optionalBankAccount.get()
|
||||||
|
bankAccount.balance = bankAccount.balance!!.add(event.creditAmount)
|
||||||
|
this.bankAccountRepository.save(bankAccount)
|
||||||
|
} else {
|
||||||
|
throw AccountNotFoundException(event.accountId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
@Throws(AccountNotFoundException::class)
|
||||||
|
fun on(event: MoneyDebitedEvent) {
|
||||||
|
log.debug("Handling an Account Debit command {}", event.accountId)
|
||||||
|
val optionalBankAccount: Optional<BankAccount> = this.bankAccountRepository.findById(event.accountId!!)
|
||||||
|
if (optionalBankAccount.isPresent) {
|
||||||
|
val bankAccount: BankAccount = optionalBankAccount.get()
|
||||||
|
bankAccount.balance = bankAccount.balance!!.subtract(event.debitAmount)
|
||||||
|
this.bankAccountRepository.save(bankAccount)
|
||||||
|
} else {
|
||||||
|
throw AccountNotFoundException(event.accountId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.cubetiqs.demo.axon.query
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
data class FindBankAccountQuery(
|
||||||
|
val id: UUID
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.cubetiqs.demo.axon.repository
|
||||||
|
|
||||||
|
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface BankAccountRepository : JpaRepository<BankAccount, UUID>
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.cubetiqs.demo.axon.service
|
||||||
|
|
||||||
|
import com.cubetiqs.demo.axon.dto.AccountCreationDTO
|
||||||
|
import com.cubetiqs.demo.axon.dto.MoneyAmountDTO
|
||||||
|
import com.cubetiqs.demo.axon.entity.BankAccount
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
@Service
|
||||||
|
interface AccountCommandService {
|
||||||
|
fun createAccount(creationDTO: AccountCreationDTO): CompletableFuture<BankAccount?>
|
||||||
|
|
||||||
|
fun creditMoneyToAccount(
|
||||||
|
accountId: String?,
|
||||||
|
moneyCreditDTO: MoneyAmountDTO
|
||||||
|
): CompletableFuture<String?>
|
||||||
|
|
||||||
|
fun debitMoneyFromAccount(
|
||||||
|
accountId: String?,
|
||||||
|
moneyDebitDTO: MoneyAmountDTO
|
||||||
|
): CompletableFuture<String?>
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.cubetiqs.demo.axon.service
|
||||||
|
|
||||||
|
import com.cubetiqs.demo.axon.command.CreateAccountCommand
|
||||||
|
import com.cubetiqs.demo.axon.command.CreditMoneyCommand
|
||||||
|
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 org.axonframework.commandhandling.gateway.CommandGateway
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.util.UUID
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class AccountCommandServiceImpl @Autowired constructor(
|
||||||
|
private val commandGateway: CommandGateway
|
||||||
|
) : AccountCommandService {
|
||||||
|
override fun createAccount(creationDTO: AccountCreationDTO): CompletableFuture<BankAccount?> {
|
||||||
|
return commandGateway.send(
|
||||||
|
CreateAccountCommand(
|
||||||
|
UUID.randomUUID(),
|
||||||
|
creationDTO.initialBalance,
|
||||||
|
creationDTO.owner,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun creditMoneyToAccount(accountId: String?, moneyCreditDTO: MoneyAmountDTO): CompletableFuture<String?> {
|
||||||
|
return commandGateway.send(
|
||||||
|
CreditMoneyCommand(
|
||||||
|
formatUuid(accountId),
|
||||||
|
moneyCreditDTO.amount
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun debitMoneyFromAccount(accountId: String?, moneyDebitDTO: MoneyAmountDTO): CompletableFuture<String?> {
|
||||||
|
return commandGateway.send(
|
||||||
|
DebitMoneyCommand(
|
||||||
|
formatUuid(accountId),
|
||||||
|
moneyDebitDTO.amount
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatUuid(accountId: String?): UUID {
|
||||||
|
return UUID.fromString(accountId)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user