From 34b3da91d68a7140df0bb2b7a83e32edcc55becc Mon Sep 17 00:00:00 2001 From: Sylvie Date: Fri, 3 May 2024 16:30:26 -0500 Subject: [PATCH 1/2] default DB settings for the more common way to run TI --- generate_env.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generate_env.sh b/generate_env.sh index 90f125646..eb06adac8 100755 --- a/generate_env.sh +++ b/generate_env.sh @@ -9,8 +9,8 @@ KEY_VAULT-NAME=ti-key-vault-name REPORT_STREAM_URL_PREFIX=http://localhost:7071 STORAGE_ACCOUNT_BLOB_ENDPOINT=https://cdctiinternal.blob.core.windows.net METADATA_CONTAINER_NAME=metadata -DB_URL=postgresql # for gradlew: DB_URL=localhost -DB_PORT=5432 # for gradlew: DB_PORT=5433 +DB_URL=localhost # if you run TI via docker: DB_URL=postgresql +DB_PORT=5433 # if you run TI via docker: DB_PORT=5432 DB_NAME=intermediary DB_USER=intermediary DB_PASS=changeIT! From a43d444a0b95d41377e54146052f95ec8a3a1a60 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Fri, 3 May 2024 16:56:01 -0500 Subject: [PATCH 2/2] add local DB info, clarify a few things --- README.md | 24 ++++++++++++++++++++---- images/docker-postgres.png | Bin 0 -> 14030 bytes 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 images/docker-postgres.png diff --git a/README.md b/README.md index ae10cdfbb..27edf4f49 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,13 @@ To run the application directly, execute... ./gradlew clean run ``` -This will run the web API on port 8080. You can view the API documentation at `/openapi`. +This runs the web API on port 8080. The app reads/writes data to a local file (unless you have a DB configured) + +You can view the API documentation at `/openapi`. ### Generating and using a token 1. Run `brew install mike-engel/jwt-cli/jwt-cli` -2. Run `jwt encode --exp='+5min' --jti $(uuidgen) --alg RS256 --no-iat -S @/PATH_TO_FILE_ON_YOUR_MACHINE/trusted-intermediary/mock_credentials/organization-trusted-intermediary-private-key-local.pem` +2. Replace `PATH_TO_FILE_ON_YOUR_MACHINE` in this command with the actual path, then run it: `jwt encode --exp='+5min' --jti $(uuidgen) --alg RS256 --no-iat -S @/PATH_TO_FILE_ON_YOUR_MACHINE/trusted-intermediary/mock_credentials/organization-trusted-intermediary-private-key-local.pem` 3. Copy token from terminal and paste into your postman body with the key `client_assertion` 4. Add a key to the body with the key `scope` and value of `trusted-intermediary` 5. Body type should be `x-wwww-form-urlencoded` @@ -32,18 +34,30 @@ The additional requirements needed to contribute towards development are... - [Python](https://docs.python-guide.org/starting/installation/) - [Terraform](https://www.terraform.io) - [Liquibase](https://www.liquibase.com/download) +- [Docker](https://www.docker.com/) ### Generating .env File -To set up the necessary environment variables, you can use the `generate_env.sh` script. This script will create a `.env` file in the resource folder with the required configuration. Follow these steps: +To set up the necessary environment variables, run the `generate_env.sh` script. This script +creates a `.env` file in the resource folder with the required configuration 1. Navigate to the project directory. - 2. Run the `generate_env.sh` script: ```bash ./generate_env.sh ``` +3. If you run TI using Docker rather than Gradle, update the DB and port values in the `.env` file (the alternate values are in comments) + +### Using a local database +Use [docker-compose.postgres.yml](docker-compose.postgres.yml) to run your local DB. In IntelliJ, you can click the play arrow to start it + +![docker-postgres.png](images/docker-postgres.png) + +Apply all outstanding migrations: +```bash +liquibase update --changelog-file ./etor/databaseMigrations/root.yml --url jdbc:postgresql://localhost:5433/intermediary --username intermediary --password 'changeIT!' --label-filter '!azure' +``` ### Compiling @@ -68,6 +82,8 @@ To run the unit tests, execute... #### End-to-end Tests End-to-end tests are meant to interact and assert the overall flow of the API is operating correctly. They require that the API to be running already. +The end-to-end tests use whatever database configuration is already in place - if you're using the local filesystem, +so will the e2e tests (this is how they work on github), and if you're using a DB, so will the tests To run them, execute... diff --git a/images/docker-postgres.png b/images/docker-postgres.png new file mode 100644 index 0000000000000000000000000000000000000000..44c6ac371f23dd14608711f6511cc3239faff117 GIT binary patch literal 14030 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 Dw4O~Z literal 0 HcmV?d00001