- JDK 21
- Groovy
- Git
- Gradle
- Lombok
- IntelliJ
- AWS Toolkit for IntelliJ
- Docker
Database
PostgreSQL
Running locally with Docker: docker compose up database -d
Spring Profile
IMPORTANT: Set your Spring active profile to dev
- this will also run DB schema/dev data migration
Backend
Java 21, Spring Boot, Gradle, Spock for testing
Running locally: ./gradlew bootRun
Frontend
React, TypeScript, scss, custom bootstrap, react-testing-library
Exception Monitoring
Sentry
Analytics
Google Analytics / Mixpanel
Hosting
AWS Elastic BeanStalk: EC2 and ELB
Continuous Integration
CircleCI
Production Logs
Papertrail
Authentication: oAuth2 with Mobile-ID, ID-card and Smart-ID
Postman API collection (outdated)
Production: Merge GitHub pull request to master -> build in CircleCI -> auto-redeploy (if build is green)
- Add the new fund to the
funds
database table.
If you don't want to run epis-service,
then you can use mock
spring profile to mock EpisService, and adjust MockEpisService
to your needs.
error="unsupported_grant_type", error_description="Unsupported grant type: mobile_id"
Make sure you are running against the right backend environment (dev or prod).
- If you do
npm run develop
yourpackage.json
must proxy tohttp://localhost:9000
- If you do
npm run develop-production
yourpackage.json
must proxy tohttps://onboarding-service.tuleva.ee
- Digital signing does not work in the dev environment. Use the production
configuration to test it locally. See
DigiDocConfiguration.digiDocConfigDev()
andsmartid.hostUrl
,smartid.relyingPartyUUID
,smartid.relyingPartyName
config values inapplication.yml
and change them to production values. Use VPN for testing.
When updating Spring Boot, sometimes you need to remove all of the existing access tokens from the
oauth_access_token
database table. However, there's one special token granted for tuleva.ee which
allows it to fetch Fund NAV values and register new users. In order to generate a new token, you need to:
token by
curl --location --request POST 'https://pension.tuleva.ee/api/oauth/token' \
--header 'Authorization: Basic <base64 of client_id:client_secret>' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=tuleva.ee'
and then update the token values in the WordPress Tuleva template.
In order to test ID-card locally, you need to run nginx locally with the right certificates and the right domain names.
- Add tuleva certs to
./nginx
(4 files) - Update
$frontend
and$backend
urls inetc/eb/.ebextensions/nginx/conf.d/01_ssl_proxy.conf
- Add to
hosts
file:127.0.0.1 id.tuleva.ee 127.0.0.1 pension.tuleva.ee 127.0.0.1 onboarding-service.tuleva.ee
- Run nginx with docker:
docker compose up nginx
- Add
DANGEROUSLY_DISABLE_HOST_CHECK=true
to.env
inonboarding-client
- add
server.servlet.session.cookie.domain: tuleva.ee
toapplication.yml
- Test through https://pension.tuleva.ee
- Later, don't forget to clean up your
hosts
file
WE use AWS SSO, to get it working properly you need to configure the profile first either by running aws configure sso
or
pasting the following into ~/.aws/config
:
[profile tuleva]
region = eu-central-1
output = json
sso_start_url = https://tuleva.awsapps.com/start
sso_region = eu-central-1
sso_account_id = 641866833894
sso_role_name = AdministratorAccess
We use AWS Client VPN. To get started, log into AWS SSO Portal and follow VPN Client Self Service instructions.
- Establish VPN connection
- Configure AWS Profile and login
aws sso login
- Connect to the DB using AWS IAM authentication where user is
iamuser
and profiletuleva
.
Configuration is available AWS S3 s3://tulevasecrets/development-configuration/
- Update
.pem
file inetc/docker
- If file was renamed, rename it in
gradle/packaging.gradle.kts
In case file has multiple certificate chains, import-certs.sh
will add all of them.
- Install keystore explorer if missing
brew install --cask keystore-explorer
or use command linekeytool
- Navigate to the
tuleva-secrets
S3 bucket, open eitherstaging
ordevelopment
directory, downloadtruststore.jks
. - Add new certs and upload new version back to S3 bucket.
- If there are errors with multiple certificates, either remove or split them by opening the
.pem
file with a text editor.- For example a root cert might be added (unnecessarily for our use case) to the cert you are trying to add to the truststore
- When changing
staging
certs, also add them tosrc/test_keys/truststore.jks
for your localdev
environment.
- If there are errors with multiple certificates, either remove or split them by opening the
- Do a clean deploy to ensure that new EC2 instance is spun up, and S3 -> EC2 files defined in
.ebextensions/keystore.config
are copied over.
PostgreSQL (used while running the application) and H2 (used while running integration tests) have slightly different support for features, requiring some to be stubbed.
When adding a new migration for H2 <-> Postgres compatibility, the name must be V1_{n-1}_1__.sql
for Flyway to execute the compatibility migration before it tries to execute the migration numbered n
, for which the compatibility migration is required.
Service logs are at tuleva-papertrail Europe (Paris) eu-west-3
which means, that you need to use eu-west-3
Aethena output S3 bucket.
Load Balancer logs are located at logs.tuleva.ee
bucket.
Service log table example
CREATE EXTERNAL TABLE IF NOT EXISTS `s3papertraillogsdatabase`.`S3PaperTrailLogsTableTSV` (
`ingestion_time` bigint,
`request_date` string,
`request_time` string,
`log_id` bigint,
`env` string,
`originating_ip` string,
`user_type` string,
`log_level` string,
`log_file` string,
`message` string
)
PARTITIONED BY (`dt` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('field.delim' = '\t')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://tuleva-papertrail/logs/';
Then run MSCK REPAIR TABLE S3PaperTrailLogsDatabase.s3papertraillogstabletsv;
For partitioning.
And query select * from s3papertraillogsdatabase.s3papertraillogstabletsv limit 10;
To configure traffic routing through a VPN split tunnel:
-
Open Client VPN endpoints and select the relevant VPN.
-
Under Route Table, create a new route specifying the desired IP address with the designated subnet.
-
In Authorization Rules, add the desired IP and set the appropriate access level.
-
If you need to register the gateway IP with an external party and need to double-check VPN internet gateway IP
- use:
dig ipv4.icanhazip.com
- And take note of the IPs for
icanhazip.com
. Add a new route and authorization rule similarly to steps 2 and 3 (currently done at ip104.16.184.241
) and establish the gateway ip - Connect to VPN
- To check VPN internet gateway IP
curl -H "Host: ipv4.icanhazip.com" http://104.16.184.241
- use: