This is work in progress - provisioning doesn't work for some reason
Fineract-CN contains of more than a dozen of micro servicesmicroservices. One doesn't need to run all of them at once - this is would be actually quite resource consuming.
These instructions list the bare minimum - getting a single micro service microservice - Identity provisioned and running.
Once you complete these steps you will get a basic understanding of how fineract-cn works and how its micro services microservices are provisioned.
Once you have completed these steps you can move on and try to provision more microservices.
You will need:
- Java8
- , Docker, docker-compose,
- Postman
P.S: it is possible to go without Docker and Docker compose (you need to install Postgres and Cassandra yourself) but we don't cover it here.
Prepare your environment
Find hosts file (/etc/hosts in Unix/Mac or c:\Windows\System32\Drivers\etc\hosts in Windows) and add:
127.0.0.1 cassandra
127.0.0.1 activemq
127.0.0.1 eureka
127.0.0.1 postgres
127.0.0.1 provisioner-ms
127.0.0.1 identity-ms
Check out the code
$ mkdir fincn_bare_minimum
$ cd fincn_bare_minimum
$ git clone https://github.com/apache/fineract-cn-identity
$ git clone https://github.com/apache/fineract-cn-provisioner
$ git clone https://github.com/apache/fineract-cn-docker-compose/
Generate RSA keys
$ java -cp fineract-cn-docker-compose/external_tools/lang-0.1.0-BUILD-SNAPSHOT.jar \
orgorg.apache.fineract.cn.lang.security.RsaKeyPairFactory SPRING > application-common.properties
Prepare common configuration
Open newly generated This generates RSA keys so the microservices trust each other. The contents of application-common.properties and add to the end of file:
...
will be something like this:
system.publicKey.exponent=65537
system.publicKey.modulus=1654279...
system.publicKey.timestamp=2019-12-10T07_53_27
system.privateKey.modulus=165427..
system.privateKey.exponent=11642831705210..#add following values
Prepare common configuration
Open newly generated application-common.properties and add this to the end of the file:
activemq.brokerUrl=tcp://activemq:61616
cassandra.cl.delete=ONE
cassandra.cl.read=ONE
cassandra.cl.write=ONE
cassandra.cluster.pwd=password
cassandra.cluster.user=cassandra
cassandra.clusterName="datacenter1"
cassandra.contactPoints=cassandra:9042
cassandra.keyspace=seshat
eureka.client.fetchRegistry=true
eureka.client.initialInstanceInfoReplicationIntervalSeconds=10
eureka.client.instanceInfoReplicationIntervalSeconds=1
eureka.client.serviceUrl.defaultZone=http://eureka:8761/eureka
eureka.client.serviceUrl.registerWithEureka=true
eureka.instance.hostname=eureka
eureka.instance.leaseRenewalIntervalInSeconds=10
eureka.registration.enabled=true
feign.hystrix.enabled=false
portfolio.bookLateFeesAndInterestAsUser=service-runner
postgresql.host=postgres
rhythm.beatCheckRate=60000
rhythm.user=imhotep
ribbon.eureka.enabled=true
ribbon.listOfServers=eureka:8761
server.max-http-header-size=24576
spring.cloud.config.enabled=false
spring.cloud.discovery.enabled=true
system.initialclientid=service-runner
Start external tools
$ cd fineract-cn-docker-compose/external_tools
$ docker-compose up -d
$ cd ../..
Now, wait for external tools (Postgre, Cassandra, ActiveMQ and Eureka) to start.
You probably will get a flollowing warning that you can safely ignore: 'WARNING: Some services (activemq, cassandra, eureka) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm."
Verify external tools have started
- Connect to Postgres database (you can use IntelliJ IDEA for that)
- jdbc:postgresql://postgres:5432/postgres (user postgres, password: postgres)
- Connect to Apache Cassandra (you can use IntelliJ IDEA for that)
- jdbc:cassandra://localhost:9042 (user cassandra)
- Eureka is available here: http://eureka:8761/
- ActiveMQ is available here: http://activemq:8161/
Run Provisioner
Open fineract-cn-provisioner with IntelliJ IDEA and wait for the project to be imported
Open ProvisionerApplication class and right-click on the class name and choose "Create ProvisionerApplication Run/Debug configuration"
...
After ~10sec you should get in terminal:
10:10:01.081 [main] INFO o.a.f.c.p.ProvisionerApplication - Started ProvisionerApplication in 11.642 seconds (JVM running for 13.988)
Verify Provisioner Micro Service started correctly
- A new schema "seshat" is created to postgres database
- A new keyspace "seshat" is created to cassandra database and the following tables are there:
- applications
- clients
- config
- tenant_applications
- tenants
- users
Run Identity Micro Service
Repeat Now we repeat the same steps (create run configuration with same program arguments) with fineract-cn-identity
In Identity the class to run is called
...
:
Open fineract-cn-identity with IntelliJ IDEA and wait for the project to be imported
Open IdentityServiceConfig class and right-click on the class name and choose "Create ProvisionerApplication Run/Debug configuration"
To program arguments set:
--spring.config.location=../application-common.properties --eureka.instance.hostname=identity-ms
Click OK and then right-click again on IdentityServiceConfig and select Run.
If you managed to do it correctly you should see in logs:
10:19:31.047 [main] INFO o.a.f.c.i.c.IdentityServiceConfig - Started IdentityServiceConfig in 7.874 seconds (JVM running for 9.701)
10:19:31.385 [DiscoveryClient-InstanceInfoReplicator-0] INFO c.netflix.discovery.DiscoveryClient - DiscoveryClient_IDENTITY-V1/192.168.1.116:identity-v1:2021 - registration status: 204
Verify Identity Micro Service has started
Open http://identity-ms:2021/ with your browser. You should get error served by microservice:
HTTP ERROR: 404
Problem accessing /info. Reason:
Not Found
Check if Identity has registered with Eureka
Wait a few minutes and open http://localhosteureka:8761/ and see if you see make sure "identity-v1" is there in the list.
Also hover Hover the link and make sure it points to identity-ms:2021/info
→ What does it mean?
Fineract-CN microservices use client-side load balancing. This works like this:
- If the microservice starts up it registers its location with Eureka. Remember we told identity that its hostname is "identity-ms"
- If some microservice X wants to connect to Identity then it asks Eureka for a location of "identity-v1"
- In development, we only have one copy of the service but in production, there could be many copies of the same service running and microservice X would choose randomly one.
Provision Identity microserviceProvision Identity micro service
We provide a postman-request-collection as well as a postman-environment that defines variables that are used to hold values received in responses.
Both files are located under fineract-cn-docker-compose/postman-initial-requests folder:
...
- Start Postman and load both files into Postman by clicking
Import
and then selecting the file. - You will see the collection "Fineract-Cn-Initial-Requests" in the left sidebar.
- Open the collection by clicking on it.
- Select the environment "Fineract-Cn-Initial-Setup-Environment" in the environment drop-down (top right corner in Postman).
- Execute the requests one by one by selecting them in the collection and then pressing "Send".
The first request (01. Log in root user) will retrieve a token. The response should look like this, with a different token:
{
"token": "Bearer eyJhbGciOiJSUzUxMiJ9.eyJhdWQiOiJwcm92aXNpb25lci12MSIsInN1YiI6IndlcGVtbmVmcmV0IiwiL21pZm9zLmlvL3NpZ25hdHVyZVRpbWVzdGFtcCI6IjIwMTctMDQtMThUMDlfNDRfMjIiLCIvbWlmb3MuaW8vdG9rZW5Db250ZW50IjoiUk9MRV9BRE1JTiIsImlzcyI6InN5c3RlbSIsImlhdCI6MTUwMDA1NjgxNywiZXhwIjoxNTAwNDE2ODE3fQ.OfxTUTStJbKQc4rAPW5PLIQYNjCG_uqcNPR4up6pIQBWLDxkgEiU9EF1WrB5NQdzXBJIHqjDFQpaVywm5DersIh4LxPGD3MZj3TqZK5_LUcZvBDTa4Xgb41e3xXkWB4TkN6KqfmiK12Ngjrrj7qZGBdtypDmFmZwKQRZIOL6T3QbI7LpbPGpeWjpWZirFgtcn5B1Z_h3r9rirCzecUdVjlaplQufxDuVFJS0R3N67pyuGQENvCAC716ID5KbokTQtITXfjnCztFuQBbtCPcYLIzxsKveyJhdWQiOiJwcm92peWjpWZirFgcYLIzxsKv_-E5k6Gd0pv01OC0XpY3NSgfAolVVgvSXKoRnL3NwAMP2yuzX6i8hR_q82Q...",
"accessTokenExpiration": "2019-07-18T22:26:57.784"
}
If you don't get a token there is something wrong with your setup. The token is necessary for authentication in other requests thus be sure that this these steps workswork. Important: Be sure to execute the requests in the right order! The outcome is often stored in variables - check the Tests section of the requests.
Only execute the following steps (besides 01 that we already did)
Execute Postman step 02.01 Create an identity-v1 application
→ in Cassandra database seshat in table applications, there should now be a record about identity-v1
Execute Postman step 03.1 Create first tenant 'playground'
→ Now wait a bit and verify the following has happened:
- In Postgres database, a new schema 'playground' is created
- In Postgres database seshat table 'tenants" contains a record about playground
- In Cassandra database, a new keyspace 'playground' is created with one empty table 'command_source'
Execute Postman step0303.2 Assign identity-v1 for Tenant and obtain Tenant Admin (user antony) Password
→ Now identity tables are created to tenant 'playground' database in cassandra.
→ Identity has a nickname 'isis' and you should see that at least 9 tables (names start with prefix 'isis_' ) have been created under Cassandra Keyspace
→ Identity doesn't keep anything in Postgre database so there are no new tables there.
Execute Postman step0303.3 Login Antony (tenant superadmin) with obtained password
03Execute Postman step03.4 Change Antony Password to 'antonyPassword'
→ Fineract forces every user to change their password on the first login. This is why we are changing the password and logging in again (in next step)
→ If we would log in with Fims Web App then the UI would tell us to change the password.
Execute Postman step0303.5 LOGIN ANTONY (tenant SuperAdmin) with pwd 'antonyPassword'
... skip a bunch of steps...
Execute Postman step0505.1 Create administrator role for tenant "playground"
05Execute Postman step05.2 Create Admin User operator with password 'initialPassword'
05Execute Postman step05.3 Log in with the initial password
05Execute Postman step05.4 Change user 'operator' password to 'operatorPassword'
...
You have now set up Identity Micro service Microservice and provisioned it using Provisioner micro servicemicroservice.
You should have schemas 'seshat' and 'playground' in Cassandra and Postgres databases.
Send your own requests to Identity
Identity Micro Service is responsible for managing users and their roles - a bit more info can be found here: Fineract CN Project Structure#identity
From identity code open UserRestController and find method getUserPermissions - this method serves the same request '05.6 Pull operator permissions' that we just sent with Postman.
Examine yourself what kind of other requests you could send to Identity.
Launch Fims Web App
You should be able to log in to Fims Web App (untested)
git clone https://github.com/apache/fineract-cn-fims-web-app
cd fineract-cn-fims-web-app
npm i
npm run dev
Open localhost:8888 and log in with
tenant: playground
user: operator
password: operatorPassword
How to reset state to start from zero
cd fineract-cn-docker-compose/external_tools
docker-compose stop
docker-compose rm -f
docker volume rm external_tools_cassandra-volume
docker volume rm external_tools_postgres-volume