Not supported by Lightbend in any conceivable way, not open for contributions.
Java 17
Apache Maven 3.6 or higher
Kalix CLI
Docker 20.10.8 or higher (client and daemon)
Container registry with public access (like Docker Hub)
Access to the gcr.io/kalix-public
container registry
cURL
IDE / editor
mvn \
archetype:generate \
-DarchetypeGroupId=io.kalix \
-DarchetypeArtifactId=kalix-spring-boot-archetype \
-DarchetypeVersion=LATEST
Define value for property 'groupId': io.kx
Define value for property 'artifactId': loan-application-spring
Define value for property 'version' 1.0-SNAPSHOT: :
Define value for property 'package' io.kx: : io.kx.loanapp
- Move
io.kx.Main
toio.kx
package - Change default annotation for
ACL
to:@Acl(allow = @Acl.Matcher(principal = Acl.Principal.ALL))
##Update pom.xml
In pom.xml
:
- In
<mainClass>io.kx.Main</mainClass>
replaceio.kx.Main
withio.kx.Main
- In
<dockerImage>my-docker-repo/${project.artifactId}</dockerImage>
replacemy-docker-repo
with the yourdockerId
- Create package
io.kx.loanapp.doman
- Create enum
LoanAppDomainStatus
- Create Java Record
LoanAppDomainState
and add parameters - Create Java Interface
LoanAppDomainEvent
and add Java records for eventsSubmitted
,Approved
,Declined
and Jackson annotations for polymorph serialization - In
LoanAppDomainState
Java Record implementempty
,onSubmitted
,onApproved
andonDeclined
methods
Tip: Check content in loan-app-step-1
git branch
- Create package
io.kx.loanapp.api
- Create Java Interface
LoanAppApi
and add Java Records for requests and responses - Create class
LoanAppService
extendingEventSourcedEntity<LoanAppDomainState>
- add class level annotations (event sourcing entity configuration):
@EntityKey("loanAppId") @EntityType("loanapp") @RequestMapping("/loanapp/{loanAppId}")
- add class level annotations (path prefix):
@RequestMapping("/loanapp/{loanAppId}")
- Override
emptyState
and returnLoanAppDomainState.empty()
, set loanAppId viaEventSourcedEntityContext
injected through the constructor - Implement each request method and event handlers
Tip: Check content in loan-app-step-1
git branch
- Create
src/test/java
- Create
io.kx.loanapp.LoanAppServiceTest
class - Implement
happyPath
Tip: Check content inloan-app-step-1
git branch
mvn test
- Edit
io.kx.loanapp.IntegrationTest
class - Implement
happyPath
Tip: Check content inloan-app-step-1
git branch
mvn -Pit verify
Note: Integration tests uses TestContainers to span integration environment so it could require some time to download required containers. Also make sure docker is running.
In project root folder there is docker-compose.yaml
for running kalix proxy
and (optionally) google pubsub emulator
.
Tip: You can comment out google pubsub emulator from docker-compose.yaml
because it is not used here
docker-compose up
Start the service:
mvn exec:exec
Submit loan application:
curl -XPOST -d '{
"clientId": "12345",
"clientMonthlyIncomeCents": 60000,
"loanAmountCents": 20000,
"loanDurationMonths": 12
}' http://localhost:9000/loanapp/1/submit -H "Content-Type: application/json"
Get loan application:
curl -XGET http://localhost:9000/loanapp/1 -H "Content-Type: application/json"
Approve:
curl -XPOST http://localhost:9000/loanapp/1/approve -H "Content-Type: application/json"
Login (need to be logged in the Kalix Console in web browser):
kalix auth login
Create new project:
kalix projects new loan-application --region gcp-us-east1
Note: Replace <REGION>
with desired region
List projects:
kalix projects list
Set project:
kalix config set project loan-application
Note: Make sure you have replaced my-docker-repo
with the your dockerId
in <dockerImage>my-docker-repo/${project.artifactId}</dockerImage>
mvn deploy
kalix services expose loan-application-spring
Result:
Service 'loan-application' was successfully exposed at: <some_host>.us-east1.kalix.app
Submit loan application:
curl -XPOST -d '{
"clientId": "12345",
"clientMonthlyIncomeCents": 60000,
"loanAmountCents": 20000,
"loanDurationMonths": 12
}' https://<somehost>.kalix.app/loanapp/1/submit -H "Content-Type: application/json"
Get loan application:
curl -XGET https://<somehost>.kalix.app/loanapp/1 -H "Content-Type: application/json"
Approve:
curl -XPOST https://<somehost>.kalix.app/loanapp/1/approve -H "Content-Type: application/json"
Create package io.kx.loanproc
in main
and test
- Create package
io.kx.loanproc.doman
- Create enum
LoanProcDomainStatus
- Create Java Record
LoanProcDomainState
- Create Java Interface
LoanProcDomainEvent
and add Java records for eventsReadyForReview
,Approved
,Declined
and Jackson annotations for polymorph serialization - In
LoanProcDomainState
Java Record implementempty
,onReadyForReview
,onApproved
andonDeclined
methods
Tip: Check content in loan-proc-step-2
git branch
- Create package
io.kx.loanproc.api
- Create Java Interface
LoanProcApi
and add Java records for requests and responses - Create class
LoanProcService
extendingEventSourcedEntity<LoanProcDomainState>
- add class level annotations (event sourcing entity configuration):
@EntityKey("loanAppId") @EntityType("loanproc") @RequestMapping("/loanproc/{loanAppId}")
- add class level annotations (path prefix):
@RequestMapping("/loanproc/{loanAppId}")
- Override
emptyState
and returnLoanProcDomainState.empty()
, set loanAppId viaEventSourcedEntityContext
injected through the constructor - Implement each request method and event handlers
Tip: Check content in loan-proc-step-2
git branch
- Create
src/test/java
- Create
io.kx.loanproc.LoanProcServiceTest
class - Create
happyPath
Tip: Check content inloan-proc-step-2
git branch
mvn test
- Edit
io.kx.loanproc.IntegrationTest
class
Tip: Check content in loan-proc-step-2
git branch
mvn -Pit verify
Note: Integration tests uses TestContainers to span integration environment so it could require some time to download required containers. Also make sure docker is running.
In project root folder there is docker-compose.yaml
for running kalix proxy
and (optionally) google pubsub emulator
.
Tip: You can comment out google pubsub emulator from docker-compose.yaml
because it is not used here
docker-compose up
Start the service:
mvn exec:exec
Start processing:
curl -XPOST http://localhost:9000/loanproc/1/process -H "Content-Type: application/json"
Get loan processing:
curl -XGET http://localhost:9000/loanproc/1 -H "Content-Type: application/json"
Approve:
curl -XPOST -d '{"reviewerId":"9999"}' http://localhost:9000/loanproc/1/approve -H "Content-Type: application/json"
mvn deploy
Start processing:
curl -XPOST https://<somehost>.kalix.app/loanproc/1/process -H "Content-Type: application/json"
Get loan processing:
curl -XGET https://<somehost>.kalix.app/loanproc/1 -H "Content-Type: application/json"
Approve:
curl -XPOST -d '{"reviewerId":"9999"}' https://<somehost>.kalix.app/loanproc/1/approve -H "Content-Type: application/json"
- Create package
io.kx.loanproc.view
- Create Java Interface
io.kx.loanproc.view.LoanProcViewModel
with Java records forViewRecord
andViewRequest
- Create
io.kx.loanproc.viewLoanProcByStatusView
class extendingView
- Add class level annotation for table name:
@Table("loanproc_by_status")
- Implement getLoanProcByStatus with
@Query
and@PostMapping
annotations - Implement event handler methods for each domain event
- Add class level annotation for table name:
Tip: Check content in views-step-3
git branch
##Unit test Because of the nature of views only Integration tests are done.
In io.kx.loanproc.IntegrationTest
copy loanProcHappyPathWith
test to loanProcHappyPathWithView
and add view query via webClient
Tip: Check content in views-step-3
git branch
mvn -Pit verify
mvn deploy
curl -XPOST -d {"statusId":"STATUS_APPROVED"} https://<somehost>.kalix.app/loanproc/views/by-status -H "Content-Type: application/json"
- Create package
io.kx.loanapp.action
- Create
io.kx.loanapp.action.LoanAppToLoanProcEventingAction
class extendingAction
- Add class level annotation:
@Subscribe.EventSourcedEntity(value = LoanAppService.class, ignoreUnknown = true)
- Inject
KalixClient
via constructor - Implement
onSubmitted
event handler method
Tip: Check content in eventing-step-4
git branch
Action for approved & declined processing event (Loan application processing service -> Loan application service)
- Create package
io.kx.loanproc.action
- Create
io.kx.loanproc.action.LoanProcToLoanAppEventingAction
class extendingAction
- Add class level annotation:
@Subscribe.EventSourcedEntity(value = LoanProcService.class, ignoreUnknown = true)
- Inject
KalixClient
via constructor - Implement
onApproved
andonDeclined
event handler methods
Tip: Check content in eventing-step-4
git branch
Update io.kx.IntegrationTest
and add endToEndHappyPath
and endToEndHappyPathWithDecline
test
Tip: Check content in eventing-step-4
git branch
mvn -Pit verify
mvn deploy
Submit loan application:
curl -XPOST -d '{
"clientId": "12345",
"clientMonthlyIncomeCents": 60000,
"loanAmountCents": 20000,
"loanDurationMonths": 12
}' https://<somehost>.kalix.app/loanapp/3/submit -H "Content-Type: application/json"
Check loan processing status:
curl -XPOST -d {"statusId":"STATUS_READY_FOR_REVIEW"} https://<somehost>.kalix.app/loanproc/views/by-status -H "Content-Type: application/json"
Approve loan processing:
curl -XPOST -d '{"reviewerId":"9999"}' https://<somehost>.kalix.app/loanproc/3/approve -H "Content-Type: application/json"
Get loan application:
curl -XGET https://<somehost>.kalix.app/loanapp/3 -H "Content-Type: application/json"
##Creating config
- Create class
io.kx.loanproc.LoanProcConfig
- Add class level annotation:
@Configuration
@ConfigurationProperties(prefix = "loanproc")
- Add parameter
Integer timeoutMillis
with getter and setter - In
src/main/resources/application.properties
addloanproc.timeoutMillis = 600000
- Create folder
src/it/resources
- Create file
src/it/resources/test.properties
and addloanproc.timeoutMillis = 5000
##Action for managing timer for timeout - Create
io.kx.loanproc.action.LoanProcTimeoutAction
class extendingAction
- Add class level annotation
@Subscribe.EventSourcedEntity(value = LoanProcService.class, ignoreUnknown = true)
- Inject
KalixClient kalixClient
andLoanProcConfig config
via constructor - Implement
getTimerName
method - Implement event handler methods for
onReadyForReview
,onApproved
andonDeclined
Tip: Check content in timers-step-5
git branch
- Update
io.kx.IntegrationTest
and addendToEndProcessingDeclinedByTimeout
test - Add class level annotation:
@TestPropertySource(locations="classpath:test.properties")
Tip: Check content intimers-step-5
git branch
mvn -Pit verify
mvn deploy
- Create
io.kx.loanapp.action.LoanAppServiceGatewayAction
class extendingAction
- add class level annotations (path prefix):
@RequestMapping("/loanapp-gw")
- add
submit
method Tip: Check content incontroller-action-step-6
git branch
Add new test case endToEndHappyPathWithGw
and use loanapp-gw
instead of loanapp
for submitting. Set loanAppId
from the response.
Tip: Check content in controller-action-step-6
git branch
mvn -Pit verify
mvn deploy