Compare commits
9 Commits
652355f486
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 16e954101f | |||
| 61369fc2bf | |||
| da16ea9afe | |||
| fedc1029ce | |||
| 857d97c142 | |||
| 4b333ff748 | |||
| 92ba0f5729 | |||
| 371c4fa5aa | |||
| 559633e58a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ build/
|
|||||||
!gradle/wrapper/gradle-wrapper.jar
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
!**/src/main/**/build/
|
!**/src/main/**/build/
|
||||||
!**/src/test/**/build/
|
!**/src/test/**/build/
|
||||||
|
application-dev.yml
|
||||||
|
|
||||||
### STS ###
|
### STS ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Spring Boot + Axon Framework
|
# Spring Boot + Axon Framework
|
||||||
### Concepts to implement
|
### Concepts to implement
|
||||||
- [ ] Event Sourcing
|
- [x] Event Sourcing
|
||||||
|
- [x] CQRS System
|
||||||
- [ ] DDD
|
- [ ] DDD
|
||||||
- [ ] CQRS System
|
|
||||||
|
|
||||||
### Contributors
|
### Contributors
|
||||||
- [x] Sambo Chea <sombochea@cubetiqs.com>
|
- [x] Sambo Chea <sombochea@cubetiqs.com>
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.cubetiqs.demo.axon
|
package com.cubetiqs.demo.axon
|
||||||
|
|
||||||
|
import com.cubetiqs.demo.axon.util.ExecUtils
|
||||||
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.http.ResponseEntity
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.util.FileCopyUtils
|
||||||
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.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
class AxonApplication
|
class AxonApplication
|
||||||
@@ -15,10 +17,13 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping
|
class MyDumper {
|
||||||
class DefaultController {
|
@GetMapping("/dump")
|
||||||
@GetMapping
|
fun dumper(
|
||||||
fun index(): ResponseEntity<Any> {
|
response: HttpServletResponse
|
||||||
return ResponseEntity.ok("ok")
|
) {
|
||||||
|
response.contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE
|
||||||
|
val data = ExecUtils.execMySqlDump()
|
||||||
|
FileCopyUtils.copy(data ?: ByteArray(0), response.outputStream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,19 +11,21 @@ import org.axonframework.commandhandling.CommandHandler
|
|||||||
import org.axonframework.eventsourcing.EventSourcingHandler
|
import org.axonframework.eventsourcing.EventSourcingHandler
|
||||||
import org.axonframework.modelling.command.AggregateIdentifier
|
import org.axonframework.modelling.command.AggregateIdentifier
|
||||||
import org.axonframework.modelling.command.AggregateLifecycle
|
import org.axonframework.modelling.command.AggregateLifecycle
|
||||||
|
import org.axonframework.serialization.Revision
|
||||||
import org.axonframework.spring.stereotype.Aggregate
|
import org.axonframework.spring.stereotype.Aggregate
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@Aggregate
|
@Aggregate
|
||||||
class BankAccountAggregate(
|
@Revision("1.0")
|
||||||
|
final class BankAccountAggregate() {
|
||||||
@AggregateIdentifier
|
@AggregateIdentifier
|
||||||
private var id: UUID? = null,
|
private var id: UUID? = null
|
||||||
private var balance: BigDecimal? = null,
|
private var balance: BigDecimal? = null
|
||||||
private var owner: String? = null
|
private var owner: String? = null
|
||||||
) {
|
|
||||||
@CommandHandler
|
@CommandHandler
|
||||||
constructor(command: CreateAccountCommand) {
|
constructor(command: CreateAccountCommand) : this() {
|
||||||
AggregateLifecycle.apply(
|
AggregateLifecycle.apply(
|
||||||
AccountCreatedEvent(
|
AccountCreatedEvent(
|
||||||
command.accountId,
|
command.accountId,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class AccountCommandController @Autowired constructor(
|
|||||||
fun debitMoneyFromAccount(
|
fun debitMoneyFromAccount(
|
||||||
@PathVariable(value = "accountId") accountId: String,
|
@PathVariable(value = "accountId") accountId: String,
|
||||||
@RequestBody moneyDebitDTO: MoneyAmountDTO
|
@RequestBody moneyDebitDTO: MoneyAmountDTO
|
||||||
): CompletableFuture<String?>? {
|
): CompletableFuture<String?> {
|
||||||
return this.accountCommandService.debitMoneyFromAccount(accountId, moneyDebitDTO)
|
return this.accountCommandService.debitMoneyFromAccount(accountId, moneyDebitDTO)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import springfox.documentation.spi.DocumentationType
|
|||||||
import springfox.documentation.spring.web.plugins.Docket
|
import springfox.documentation.spring.web.plugins.Docket
|
||||||
import springfox.documentation.swagger2.annotations.EnableSwagger2
|
import springfox.documentation.swagger2.annotations.EnableSwagger2
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableSwagger2
|
@EnableSwagger2
|
||||||
|
|||||||
17
src/main/kotlin/com/cubetiqs/demo/axon/config/WebConfig.kt
Normal file
17
src/main/kotlin/com/cubetiqs/demo/axon/config/WebConfig.kt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package com.cubetiqs.demo.axon.config
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
class WebConfig : WebMvcConfigurer {
|
||||||
|
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
|
||||||
|
registry.addResourceHandler("swagger-ui.html")
|
||||||
|
.addResourceLocations("classpath:/META-INF/resources/")
|
||||||
|
registry.addResourceHandler("/webjars/**")
|
||||||
|
.addResourceLocations("classpath:/META-INF/resources/webjars/")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ import java.io.Serializable
|
|||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.persistence.Entity
|
import javax.persistence.Entity
|
||||||
import javax.persistence.GeneratedValue
|
|
||||||
import javax.persistence.GenerationType
|
|
||||||
import javax.persistence.Id
|
import javax.persistence.Id
|
||||||
import javax.persistence.Table
|
import javax.persistence.Table
|
||||||
|
|
||||||
@@ -13,7 +11,6 @@ import javax.persistence.Table
|
|||||||
@Table(name = "bank_accounts")
|
@Table(name = "bank_accounts")
|
||||||
data class BankAccount(
|
data class BankAccount(
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
var id: UUID? = null,
|
var id: UUID? = null,
|
||||||
|
|
||||||
var owner: String? = null,
|
var owner: String? = null,
|
||||||
|
|||||||
@@ -62,6 +62,6 @@ class BankAccountProjection @Autowired constructor(
|
|||||||
@QueryHandler
|
@QueryHandler
|
||||||
fun handle(query: FindBankAccountQuery): BankAccount? {
|
fun handle(query: FindBankAccountQuery): BankAccount? {
|
||||||
log.debug("Handling FindBankAccountQuery query: {}", query)
|
log.debug("Handling FindBankAccountQuery query: {}", query)
|
||||||
return this.bankAccountRepository.findById(query.accountId).orElse(null)
|
return this.bankAccountRepository.findById(query.id).orElse(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,5 +3,5 @@ package com.cubetiqs.demo.axon.query
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
data class FindBankAccountQuery(
|
data class FindBankAccountQuery(
|
||||||
val accountId: UUID
|
val id: UUID
|
||||||
)
|
)
|
||||||
@@ -44,6 +44,4 @@ class AccountCommandServiceImpl @Autowired constructor(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
43
src/main/kotlin/com/cubetiqs/demo/axon/util/ExecUtils.kt
Normal file
43
src/main/kotlin/com/cubetiqs/demo/axon/util/ExecUtils.kt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package com.cubetiqs.demo.axon.util
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
object ExecUtils {
|
||||||
|
private const val MYSQLDUMP_FILE = "mysqldump"
|
||||||
|
|
||||||
|
fun execMySqlDump(): ByteArray? {
|
||||||
|
var results: ByteArray?
|
||||||
|
try {
|
||||||
|
val command: MutableList<String> = mutableListOf()
|
||||||
|
command.add(MYSQLDUMP_FILE)
|
||||||
|
command.add("--databases")
|
||||||
|
command.add("orderwebapp")
|
||||||
|
command.add("--host")
|
||||||
|
command.add("192.168.0.204")
|
||||||
|
command.add("-usombochea")
|
||||||
|
command.add("-p@Csb632612")
|
||||||
|
|
||||||
|
val builder = ProcessBuilder(*command.toTypedArray())
|
||||||
|
.redirectErrorStream(false)
|
||||||
|
val process = builder.start()
|
||||||
|
BufferedInputStream(process.inputStream).use {
|
||||||
|
ByteArrayOutputStream().use { stdout ->
|
||||||
|
while (true) {
|
||||||
|
val x = it.read()
|
||||||
|
if (x == -1) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
stdout.write(x)
|
||||||
|
}
|
||||||
|
results = stdout.toByteArray()
|
||||||
|
process.waitFor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println(e.message)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,13 @@ server:
|
|||||||
port: 8182
|
port: 8182
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
|
application:
|
||||||
|
name: axon-demo
|
||||||
datasource:
|
datasource:
|
||||||
driverClassName: org.postgresql.Driver
|
driverClassName: org.postgresql.Driver
|
||||||
url: jdbc:postgresql://${POSTGRES_HOST:192.168.0.202}:${POSTGRES_PORT:5432}/${POSTGRES_DB:axon_demo}
|
url: jdbc:postgresql://${POSTGRES_HOST:localhost}:${POSTGRES_PORT:5432}/${POSTGRES_DB:axon_demo}
|
||||||
username: ${POSTGRES_USERNAME:cubetiq}
|
username: ${POSTGRES_USERNAME:root}
|
||||||
password: ${POSTGRES_PASSWORD:Root$}
|
password: ${POSTGRES_PASSWORD:root}
|
||||||
hikari:
|
hikari:
|
||||||
max-lifetime: 1800000
|
max-lifetime: 1800000
|
||||||
connection-timeout: 30000
|
connection-timeout: 30000
|
||||||
@@ -34,3 +36,8 @@ spring:
|
|||||||
axon:
|
axon:
|
||||||
serializer:
|
serializer:
|
||||||
general: jackson
|
general: jackson
|
||||||
|
axonserver:
|
||||||
|
servers: localhost
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level.root: debug
|
||||||
10
src/test/kotlin/TestExecUtils.kt
Normal file
10
src/test/kotlin/TestExecUtils.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import com.cubetiqs.demo.axon.util.ExecUtils
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class TestExecUtils {
|
||||||
|
@Test
|
||||||
|
fun dump() {
|
||||||
|
val dump = ExecUtils.execMySqlDump()
|
||||||
|
println("Dump size: ${dump?.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user