Java 11 or later
SBT 1.3.6 or later
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
sbt new lightbend/kalix-value-entity.g8
name [My Kalix Project]: loan-application
sdk_version [1.0.1]:
sbt_version [1.6.2]:
scala_version [2.13.7]:
package [com.example]: io.kx.loanapp
Delete all proto files after done
In build.sbt
add:
mainClass := Option("io")
version := "1.0-SNAPSHOT
Create io/kx/loanapp/api
folder in src/main/proto
folder.
Create loan_app_api.proto
in src/main/proto/io/kx/loanapp/api
folder.
Create:
- headers
- state
- commands
- service
Tip: Check content in step-1
git branch
Create io/kx/loanapp/doman
folder in src/main/proto
folder.
Create loan_app_domain.proto
in src/main/proto/io/kx/loanapp/domain
folder.
Create:
- headers
- state
- events
Tip: Check content in step-1
git branch
In src/main/proto/io/kx/loanapp/api/loan_app_api.proto
add AkkaServerless codegen annotations to GRPC service
service LoanAppService {
option (kalix.codegen) = {
event_sourced_entity: {
name: "io.kx.loanapp.domain.LoanAppEntity"
entity_type: "loanapp"
state: "io.kx.loanapp.domain.LoanAppDomainState"
events: [
"io.kx.loanapp.domain.Submitted",
"io.kx.loanapp.domain.Approved",
"io.kx.loanapp.domain.Declined"
]
}
};
...
Note: event_sourced_entity.name
has to be a unique name
sbt compile
Compile will generate help classes and these skeleton classes
Business logic:
src/main/scala/io/Main
src/main/scala/io/kx/loanapp/domain/LoanAppEntity
Unit tests:
src/test/scala/io/kx/loanapp/domain/LoanAppEntitySpec
Integration tests:
src/test/scala/io/kx/loanapp/api/LoanAppServiceIntegrationSpec
Implement src/main/scala/io/kx/loanapp/domain/LoanAppEntity
class
Tip: Check content in step-1
git branch
Implement src/test/scala/io/kx/loanapp/domain/LoanAppEntitySpec
class
Tip: Check content in step-1
git branch
Implement src/test/scala/io/kx/loanapp/api/LoanAppServiceIntegrationSpec
class
Tip: Check content in step-1
git branch
sbt test
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: If you do not require google pubsub emulator then comment it out in docker-compose.yaml
docker-compose up
Start the service:
sbt compile run
Submit loan application:
curl -XPOST -d '{
"client_id": "12345",
"client_monthly_income_cents": 60000,
"loan_amount_cents": 20000,
"loan_duration_months": 12
}' http://localhost:9000/loanapp/1 -H "Content-Type: application/json"
Get loan application:
curl -XGET http://localhost:9000/loanapp/1 -H "Content-Type: application/json"
Approve:
curl -XPUT http://localhost:9000/loanapp/1/approve -H "Content-Type: application/json"
sbt docker:publish -Ddocker.username=<dockerId>
Note: Replace <dockerId>
with required dockerId
Validate version:
kalix version
Login (need to be logged in the Kalix Console in web browser):
kalix auth login
Create new project:
kalix projects new loan-application --region <REGION>
Note: Replace <REGION>
with desired region
List projects:
kalix projects list
Set project:
kalix config set project loan-application
kalix service deploy loan-application my-docker-repo/loan-application:1.0-SNAPSHOT
Note: Replace my-docker-repo
with your docker repository
List services:
kalix services list
NAME AGE REPLICAS STATUS DESCRIPTION
loan-application 102s 1 Ready
kalix services expose loan-application
Result:
Service 'loan-application' was successfully exposed at: lingering-morning-1201.us-east1.kalix.app
Submit loan application:
curl -XPOST -d '{
"client_id": "12345",
"client_monthly_income_cents": 60000,
"loan_amount_cents": 20000,
"loan_duration_months": 12
}' https://lingering-morning-1201.us-east1.kalix.app/loanapp/1 -H "Content-Type: application/json"
Get loan application:
curl -XGET https://lingering-morning-1201.us-east1.kalix.app/loanapp/1 -H "Content-Type: application/json"
Approve:
curl -XPUT https://lingering-morning-1201.us-east1.kalix.app/loanapp/1/approve -H "Content-Type: application/json"
In build.sbt
set version
to 1.1-SNAPSHOT
Create io/kx/loanproc/api
folder in src/main/proto
folder.
Create loan_proc_api.proto
in src/main/proto/io/kx/loanproc/api
folder.
Create:
- state
- commands
- service
Tip: Check content in step-2
git branch
Create io/kx/loanproc/domain
folder in src/main/proto
folder.
Create loan_proc_domain.proto
in src/main/proto/io/kx/loanproc/domain
folder.
Create:
- state
- events
Tip: Check content in step-2
git branch
In src/main/proto/io/kx/loanproc/api/loan_proc_api.proto
add AkkaServerless codegen annotations to GRPC service
service LoanProcService {
option (kalix.codegen) = {
event_sourced_entity: {
name: "io.kx.loanproc.domain.LoanProcEntity"
entity_type: "loanproc"
state: "io.kx.loanproc.domain.LoanProcDomainState"
events: [
"io.kx.loanproc.domain.ProcessStarted",
"io.kx.loanproc.domain.Approved",
"io.kx.loanproc.domain.Declined"
]
}
};
...
Note: event_sourced_entity.name
has to be a unique name
sbt compile
Compile will generate these skeleton classes
Business logic:
src/main/scala/io/kx/loanproc/domain/LoanProcEntity
Unit tests:
src/test/scala/io/kx/loanproc/domain/LoanProcEntityTest
Integration tests:
src/test/scala/io/kx/loanproc/api/LoanProcEntityIntegrationTest
In src/main/scala/io/Main
you need to add new entity component (LoanProcEntity
):
KalixFactory.withComponents(
new LoanAppEntity(_),new LoanProcEntity(_))
Implement src/main/scala/io/kx/loanproc/domain/LoanProcEntity
class
Tip: Check content in step-2
git branch
Implement src/test/scala/io/kx/loanproc/domain/LoanProcEntitySpec
class
Tip: Check content in step-2
git branch
Implement src/test/scala/io/kx/loanproc/api/LoanProcServiceIntegrationSpec
class
Tip: Check content in step-2
git branch
sbt test
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.
sbt docker:publish -Ddocker.username=<dockerId>
Note: Replace <dockerId>
with required dockerId
kalix service deploy loan-application my-docker-repo/loan-application:1.1-SNAPSHOT
Note: Replace my-docker-repo
with your docker repository
Start processing:
curl -XPOST -d '{
"client_monthly_income_cents": 60000,
"loan_amount_cents": 20000,
"loan_duration_months": 12
}' https://lingering-morning-1201.us-east1.kalix.app/loanproc/1 -H "Content-Type: application/json"
Get loan processing:
curl -XGET https://lingering-morning-1201.us-east1.kalix.app/loanproc/1 -H "Content-Type: application/json"
Approve:
curl -XPUT https://lingering-morning-1201.us-east1.kalix.app/loanproc/1/approve -H "Content-Type: application/json"
In build.sbt
set version
to 1.2-SNAPSHOT
Create io/kx/loanproc/view
folder in src/main/proto
folder.
Create loan_proc_by_status_view.proto
in src/main/proto/io/kx/loanproc/view
folder.
Create:
- state
- request/response
- service
Note: SELECT
result alias AS results
needs to correspond with GetLoanProcByStatusResponse
parameter name repeated LoanProcViewState results
Note: Currently enums
are not supported as query parameters (issue 1141) so enum number
value is used for query
Tip: Check content in step-3
git branch
sbt compile
Compile will generate help classes (target/generated-*
folders) and skeleton classes
src/main/scala/io/kx/loanproc/view/LoanProcByStatusView
In src/main/scala/io/Main
you need to add view (LoanProcByStatusView
) initialization:
KalixFactory.withComponents(
new LoanAppEntity(_),new LoanProcEntity(_), new LoanProcByStatusView(_))
Implement src/main/scala/io/kx/loanproc/view/LoanProcByStatusView
class
Tip: Check content in step-3
git branch
##Unit test
Because of the nature of views only Integration tests are done.
- Copy
io/kx/loanproc/api/LoanProcServiceIntegrationSpec
class toio/kx/loanproc/api/LoanProcServiceViewIntegrationSpec
- Remove all tests in
- Add next to
clien declaration
:
private val view = testKit.getGrpcClient(classOf[LoanProcByStatus])
- Add
view test
Tip: Check content in step-3
git branch
sbt test
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.
sbt docker:publish -Ddocker.username=<dockerId>
Note: Replace <dockerId>
with required dockerId
kalix service deploy loan-application my-docker-repo/loan-application:1.2-SNAPSHOT
Note: Replace my-docker-repo
with your docker repository
Get loan processing by status:
curl -XPOST -d {"status_id":2} https://lingering-morning-1201.us-east1.kalix.app/loanproc/views/by-status -H "Content-Type: application/json"
In build.sbt
set version
to 1.3-SNAPSHOT
Create io/kx/loanapp/action
folder in src/main/proto
folder.
Create loan_app_eventing_to_proc_action.proto
in src/main/proto/io/kx/loanapp/action
folder.
Create:
- service
Tip: Check content in step-4
git branch
Action for approved & declined processing event (Loan application processing service -> Loan application service)
Create io/kx/loanproc/action
folder in src/main/proto
folder.
Create loan_proc_eventing_to_app_action.proto
in src/main/proto/io/kx/loanproc/action
folder.
Create:
- service
Tip: Check content in step-4
git branch
mvn sbt
Compile will generate skeleton classes:
src/main/scala/io/kx/loanapp/action/LoanAppEventingToProcAction
src/main/scala/io/kx/loanproc/action/LoanProcEventingToAppAction
In src/main/scala/io/Main
you need to add view (LoanAppEventingToProcAction
& LoanProcEventingToAppAction
) initialization:
KalixFactory.withComponents(
new LoanAppEntity(_),new LoanProcEntity(_), new LoanAppEventingToProcAction(_), new LoanProcByStatusView(_), new LoanProcEventingToAppAction(_))
Implement src/main/scala/io/kx/loanapp/action/LoanAppEventingToProcAction
class
Tip: Check content in step-4
git branch
Implement src/main/scala/io/kx/loanproc/action/LoanProcEventingToAppAction
class
Tip: Check content in step-4
git branch
In src/test/scala/io/kx
folder create new class SustemIntegrationSpec
.
Tip: Check content in step-4
git branch
sbt test
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.
sbt docker:publish -Ddocker.username=<dockerId>
Note: Replace <dockerId>
with required dockerId
kalix service deploy loan-application my-docker-repo/loan-application:1.3-SNAPSHOT
Note: Replace my-docker-repo
with your docker repository
Submit loan application:
curl -XPOST -d '{
"client_id": "123456",
"client_monthly_income_cents": 60000,
"loan_amount_cents": 20000,
"loan_duration_months": 12
}' https://lingering-morning-1201.us-east1.kalix.app/loanapp/2 -H "Content-Type: application/json"
Approve loan processing:
curl -XPUT -d '{
"reviewer_id": "9999"
}' https://lingering-morning-1201.us-east1.kalix.app/loanproc/2/approve -H "Content-Type: application/json"
Get loan application :
curl -XGET https://lingering-morning-1201.us-east1.kalix.app/loanapp/2 -H "Content-Type: application/json"