diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 73a049858d..c65f9db426 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -61,11 +61,6 @@ }, "mounts": [], - // Use 'forwardPorts' to make a list of ports inside the container available locally. - "forwardPorts": [ - 9060, - 9061 - ], "postCreateCommand": "bash ./.devcontainer/post-install.sh" } \ No newline at end of file diff --git a/.vscode-sample/multitenant.yml b/.vscode-sample/alice.yml similarity index 51% rename from .vscode-sample/multitenant.yml rename to .vscode-sample/alice.yml index 68888a5bb2..36886aa014 100644 --- a/.vscode-sample/multitenant.yml +++ b/.vscode-sample/alice.yml @@ -1,22 +1,25 @@ +# Alice agent configuration + auto-provision: true -label: vscode +label: alice inbound-transport: - - [http, 0.0.0.0, 9060] + - [http, 0.0.0.0, 9010] outbound-transport: http -emit-new-didcomm-prefix: true wallet-type: askar wallet-storage-type: default +wallet-name: alice-wallet +wallet-key: alice-wallet-key admin-insecure-mode: true -admin: [0.0.0.0, 9061] +admin: [0.0.0.0, 9011] -endpoint: http://host.docker.internal:9060 +endpoint: http://localhost:9010 -genesis-url: http://test.bcovrin.vonx.io/genesis +genesis-url: http://localhost:9000/genesis # Connections debug-connections: true @@ -24,9 +27,6 @@ auto-accept-invites: true auto-accept-requests: true auto-ping-connection: true -# multitenant -multitenant: true -multitenant-admin: true -jwt-secret: changeme - log-level: info + +tails-server-base-url: http://localhost:6543 \ No newline at end of file diff --git a/.vscode-sample/author.yml b/.vscode-sample/author.yml new file mode 100644 index 0000000000..758fd97535 --- /dev/null +++ b/.vscode-sample/author.yml @@ -0,0 +1,42 @@ +# Author agent configuration + +auto-provision: true +label: author + +inbound-transport: + - [http, 0.0.0.0, 9020] + +outbound-transport: http + +wallet-type: askar +wallet-storage-type: default +wallet-name: author-wallet +wallet-key: author-wallet-key + +admin-insecure-mode: true + +admin: [0.0.0.0, 9021] + +endpoint: http://localhost:9020 + +genesis-url: http://localhost:9000/genesis + +# Connections +debug-connections: true +auto-accept-invites: true +auto-accept-requests: true +auto-ping-connection: true + +log-level: info + +tails-server-base-url: https://localhost:6543 + +# endorser info configuration +endorser-alias: endorser +endorser-protocol-role: author +auto-request-endorsement: true +auto-write-transactions: true +# endorser-public-did: FsTs4Xb4PHwb6BxyFPFfYd +auto-promote-author-did: true +auto-create-revocation-transactions: true +# endorser-invitation: http://localhost:9060?oob=eyJAdHlwZSI6ICJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW5kLzEuMS9pbnZpdGF0aW9uIiwgIkBpZCI6ICIwOWU3MDRmOC04YzUxLTQzNTktOTg2YS0xZmI5YTIzYmQxODciLCAibGFiZWwiOiAiZW5kb3JzZXIiLCAiaGFuZHNoYWtlX3Byb3RvY29scyI6IFsiaHR0cHM6Ly9kaWRjb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiXSwgInNlcnZpY2VzIjogW3siaWQiOiAiI2lubGluZSIsICJ0eXBlIjogImRpZC1jb21tdW5pY2F0aW9uIiwgInJlY2lwaWVudEtleXMiOiBbImRpZDprZXk6ejZNa3ZNUFlNYUdGTVFTRFhQc2o4OUNobTY0aVIyYmE0U1hZY3ZON2JCeUNkNWJoI3o2TWt2TVBZTWFHRk1RU0RYUHNqODlDaG02NGlSMmJhNFNYWWN2TjdiQnlDZDViaCJdLCAic2VydmljZUVuZHBvaW50IjogImh0dHA6Ly9sb2NhbGhvc3Q6OTA2MCJ9XX0= \ No newline at end of file diff --git a/.vscode-sample/endorser.yml b/.vscode-sample/endorser.yml new file mode 100644 index 0000000000..76ad57b2f4 --- /dev/null +++ b/.vscode-sample/endorser.yml @@ -0,0 +1,36 @@ +# Endorser agent configuration + +auto-provision: true +label: endorser + +inbound-transport: + - [http, 0.0.0.0, 9030] + +outbound-transport: http + +wallet-type: askar +wallet-storage-type: default +wallet-name: endorser-wallet +wallet-key: endorser-wallet-key + +admin-insecure-mode: true + +admin: [0.0.0.0, 9031] + +endpoint: http://localhost:9030 + +genesis-url: http://localhost:9000/genesis + +# Connections +debug-connections: true +auto-accept-invites: true +auto-accept-requests: true +auto-ping-connection: true + +log-level: info + +tails-server-base-url: http://localhost:6543 + +# endorser +endorser-protocol-role: endorser +auto-endorse-transactions: true \ No newline at end of file diff --git a/.vscode-sample/faber.yml b/.vscode-sample/faber.yml new file mode 100644 index 0000000000..990b1da26b --- /dev/null +++ b/.vscode-sample/faber.yml @@ -0,0 +1,32 @@ +# Faber agent configuration + +auto-provision: true +label: faber + +inbound-transport: + - [http, 0.0.0.0, 9040] + +outbound-transport: http + +wallet-type: askar +wallet-storage-type: default +wallet-name: faber-wallet +wallet-key: faber-wallet-key + +admin-insecure-mode: true + +admin: [0.0.0.0, 9041] + +endpoint: http://localhost:9040 + +genesis-url: http://localhost:9000/genesis + +# Connections +debug-connections: true +auto-accept-invites: true +auto-accept-requests: true +auto-ping-connection: true + +log-level: info + +tails-server-base-url: http://localhost:6543 \ No newline at end of file diff --git a/.vscode-sample/launch.json b/.vscode-sample/launch.json index 2eae0a1f9f..a315b66c6f 100644 --- a/.vscode-sample/launch.json +++ b/.vscode-sample/launch.json @@ -5,14 +5,58 @@ "version": "0.2.0", "configurations": [ { - "name": "Run/Debug ACA-Py", + "name": "Run/Debug Faber", "type": "python", "request": "launch", "module": "aries_cloudagent", "justMyCode": true, "args": [ "start", - "--arg-file=${workspaceRoot}/.vscode/multitenant.yml" + "--arg-file=${workspaceRoot}/.vscode/faber.yml" + ] + }, + { + "name": "Run/Debug Alice", + "type": "python", + "request": "launch", + "module": "aries_cloudagent", + "justMyCode": true, + "args": [ + "start", + "--arg-file=${workspaceRoot}/.vscode/alice.yml" + ] + }, + { + "name": "Run/Debug Endorser", + "type": "python", + "request": "launch", + "module": "aries_cloudagent", + "justMyCode": true, + "args": [ + "start", + "--arg-file=${workspaceRoot}/.vscode/endorser.yml" + ] + }, + { + "name": "Run/Debug Author", + "type": "python", + "request": "launch", + "module": "aries_cloudagent", + "justMyCode": true, + "args": [ + "start", + "--arg-file=${workspaceRoot}/.vscode/author.yml" + ] + }, + { + "name": "Run/Debug Multitenant Admin", + "type": "python", + "request": "launch", + "module": "aries_cloudagent", + "justMyCode": true, + "args": [ + "start", + "--arg-file=${workspaceRoot}/.vscode/multitenant-admin.yml" ] }, { @@ -24,7 +68,7 @@ "sudo": true, "justMyCode": true, "cwd": "${workspaceFolder}/aries_cloudagent", - "args": ["check", "."], + "args": ["check", "."] }, { "name": "ruff fix - aries_cloudagent", @@ -35,7 +79,7 @@ "sudo": true, "justMyCode": true, "cwd": "${workspaceFolder}/aries_cloudagent", - "args": ["check", ".", "--fix"], + "args": ["check", ".", "--fix"] }, { "name": "ruff - current file", @@ -46,7 +90,7 @@ "sudo": true, "justMyCode": true, "cwd": "${workspaceFolder}/aries_cloudagent", - "args": ["check", ".", "${file}"], + "args": ["check", ".", "${file}"] }, { "name": "black (check) - aries_cloudagent", @@ -59,7 +103,7 @@ "args": [ ".", "--check" - ], + ] }, { "name": "black (check) - current file", @@ -71,7 +115,7 @@ "args": [ "${file}", "--check" - ], + ] }, { "name": "black (format) - aries_cloudagent", @@ -83,7 +127,7 @@ "cwd": "${workspaceFolder}/aries_cloudagent", "args": [ "." - ], + ] }, { "name": "black (format) - current file", @@ -93,8 +137,8 @@ "console": "integratedTerminal", "justMyCode": true, "args": [ - "${file}", - ], - }, + "${file}" + ] + } ] } \ No newline at end of file diff --git a/.vscode-sample/multitenant-admin.yml b/.vscode-sample/multitenant-admin.yml new file mode 100644 index 0000000000..b6f98ef4fa --- /dev/null +++ b/.vscode-sample/multitenant-admin.yml @@ -0,0 +1,37 @@ +# Multitenant admin agent configuration + +auto-provision: true +label: multitenant-admin + +inbound-transport: + - [http, 0.0.0.0, 9050] + +outbound-transport: http + +wallet-type: askar-anoncreds +wallet-storage-type: default +wallet-name: multitenant-admin-wallet +wallet-key: multitenant-admin-wallet-key + +admin-insecure-mode: true + +admin: [0.0.0.0, 9051] + +endpoint: http://localhost:9050 + +genesis-url: https://localhost:9000/genesis + +# Connections +debug-connections: true +auto-accept-invites: true +auto-accept-requests: true +auto-ping-connection: true + +# Multi-tenancy +multitenant: true +jwt-secret: insecure-jwt-secret +multitenant-admin: true + +log-level: info + +tails-server-base-url: https://localhost:6543 diff --git a/.vscode-sample/settings.json b/.vscode-sample/settings.json index cd0a79cb6a..69a76f9b24 100644 --- a/.vscode-sample/settings.json +++ b/.vscode-sample/settings.json @@ -1,3 +1,3 @@ { - "python.testing.pytestArgs": ["--no-cov"], + "python.testing.pytestArgs": ["--no-cov"] } \ No newline at end of file diff --git a/DevReadMe.md b/DevReadMe.md index b892e83443..96021db34a 100644 --- a/DevReadMe.md +++ b/DevReadMe.md @@ -140,9 +140,15 @@ ACA-Py can issue W3C Verifiable Credentials using Linked Data Proofs. See the [d [Docker](https://www.docker.com) must be installed to run software locally and to run the test suite. +### Running In A Dev Container + +The dev container environment is a great way to deploy agents quickly with code changes and an interactive debug session. Detailed information can be found in the [Docs On Devcontainers](devcontainer.md). It is specific for vscode, so if you prefer another code editor or IDE you will need to figure it out on your own, but it is highly recommended to give this a try. + +One thing to be aware of is, unlike the demo, none of the steps are automated. You will need to create public dids, connections and all the other steps yourself. Using the demo and studying the flow and then copying them with your dev container debug session is a great way to learn how everything works. + ### Running Locally -For local development, we recommend using the provided Docker scripts to run the ACA-Py software. +Another way to develop locally is by using the provided Docker scripts to run the ACA-Py software. ```bash ./scripts/run_docker start diff --git a/devcontainer.md b/devcontainer.md index ca53a8c83f..cbc2a09f9e 100644 --- a/devcontainer.md +++ b/devcontainer.md @@ -15,34 +15,6 @@ There are limitations running this devcontainer, such as all networking is withi ### Files The `.devcontainer` folder contains the `devcontainer.json` file which defines this container. We are using a `Dockerfile` and `post-install.sh` to build and configure the container run image. The `Dockerfile` is simple but in place for simplifying image enhancements (ex. adding `poetry` to the image). The `post-install.sh` will install some additional development libraries (including for BDD support). -### Poetry -The Python libraries / dependencies are installed using [`poetry`](https://python-poetry.org). For the devcontainer, we *DO NOT* use virtual environments. This means you will not see or need venv prompts in the terminals and you will not need to run tasks through poetry (ie. `poetry run black .`). If you need to add new dependencies, you will need to add the dependency via poetry *AND* you should rebuild your devcontainer. - -### Running docker-in-docker demos -The following is an example of running the demos in this container using a local [von-network](https://github.com/bcgov/von-network/tree/main). You will have to connect to the local von-network using `host.docker.internal` not `localhost`. - -Assumes von-network is running outside of VS Code and this container at the default port (9000). - -```sh -# open a terminal in VS Code... -cd demo -LEDGER_URL=http://host.docker.internal:9000 ./run_demo faber -# open a second terminal in VS Code... -cd demo -LEDGER_URL=http://host.docker.internal:9000 ./run_demo alice -# follow the script... -``` - - -## Further Reading and Links - -* Development Containers (devcontainers): [https://containers.dev](https://containers.dev) -* Visual Studio Code: [https://code.visualstudio.com](https://code.visualstudio.com) -* Dev Containers Extension: [marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -* Docker: [https://www.docker.com](https://www.docker.com) -* Docker Compose: [https://docs.docker.com/compose/](https://docs.docker.com/compose/) - - ## Devcontainer > What are Development Containers? @@ -70,7 +42,10 @@ To open ACA-Py in a devcontainer, we open the *root* of this repository. We can #### devcontainer.json -When the [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json) is opened, you will see it building... it is building a Python 3.9 image (bash shell) and loading it with all the ACA-Py requirements (and black). Since this is a Docker container, we will also open ports `9060` and `9061`, allowing you to run/debug ACA-Py with those ports available to your `localhost` (more on those later). We also load a few Visual Studio settings (for running Pytests and formatting with Flake and Black). +When the [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json) is opened, you will see it building... it is building a Python 3.9 image (bash shell) and loading it with all the ACA-Py requirements (and black). We also load a few Visual Studio settings (for running Pytests and formatting with Flake and Black). + +### Poetry +The Python libraries / dependencies are installed using [`poetry`](https://python-poetry.org). For the devcontainer, we *DO NOT* use virtual environments. This means you will not see or need venv prompts in the terminals and you will not need to run tasks through poetry (ie. `poetry run black .`). If you need to add new dependencies, you will need to add the dependency via poetry *AND* you should rebuild your devcontainer. In VS Code, open a Terminal, you should be able to run the following commands: @@ -79,6 +54,7 @@ python -m aries_cloudagent -v cd aries_cloudagent ruff check . black . --check +poetry --version ``` The first command should show you that `aries_cloudagent` module is loaded (ACA-Py). The others are examples of code quality checks that ACA-Py does on commits (if you have [`precommit`](https://pre-commit.com) installed) and Pull Requests. @@ -100,7 +76,49 @@ We have added Black formatter and Ruff extensions. Although we have added launch More importantly, these extensions are now added to document save, so files will be formatted and checked. We advise that after each time you rebuild the container that you also perform: `Developer: Reload Window` to ensure the extensions are loaded correctly. -## Debugging +### Running docker-in-docker demos + +Start by running a von-network inside your dev container. Or connect to a hosted ledger. You will need to adjust the ledger configurations if you do this. + +```sh +git clone https://github.com/bcgov/von-network +cd von-network +./manage build +./manage start +cd .. +``` + +If you want to have revocation then start up a tails server in your dev container. Or connect to a hosted tails server. Once again you will need to adjust the configurations. + +```sh +git clone https://github.com/bcgov/indy-tails-server.git +cd indy-tails-server/docker +./manage build +./manage start +cd ../.. +``` + +```sh +# open a terminal in VS Code... +cd demo +./run_demo faber +# open a second terminal in VS Code... +cd demo +./run_demo alice +# follow the script... +``` + + +## Further Reading and Links + +* Development Containers (devcontainers): [https://containers.dev](https://containers.dev) +* Visual Studio Code: [https://code.visualstudio.com](https://code.visualstudio.com) +* Dev Containers Extension: [marketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +* Docker: [https://www.docker.com](https://www.docker.com) +* Docker Compose: [https://docs.docker.com/compose/](https://docs.docker.com/compose/) + + +## ACA-Py Debugging To better illustrate debugging pytests and ACA-Py runtime code, let's add some run/debug configurations to VS Code. If you have your own `launch.json` and `settings.json`, please cut and paste what you want/need. @@ -108,47 +126,59 @@ To better illustrate debugging pytests and ACA-Py runtime code, let's add some r cp -R .vscode-sample .vscode ``` -This will add a `launch.json`, `settings.json` and an ACA-Py configuration file: `multitenant.yml`. +This will add a `launch.json`, `settings.json` and multiple ACA-Py configuration files for developing with different scenarios. -### Pytest + Faber: Simple agent to simulate an issuer + Alice: Simple agent to simulate a holder + Endorser: Simulates the endorser agent in an endorsement required environment + Author: Simulates an author agent in a endorsement required environment + Multitenant Admin: Includes settings for a multitenant/wallet scenario -Pytest is installed and almost ready; however, we must build the test list. In the Command Palette, `Test: Refresh Tests` will scan and find the tests. +Having multiple agents is to demonstrate launching multiple agents in a debug session. Any of the config files and the launch file can be changed and customized to meet your needs. They are all setup to run on different ports so they don't interfere with each other. Running the debug session from inside the dev container allows you to contact other services such as a local ledger or tails server using localhost, while still being able to access the swagger admin api through your browser. -See [Python Testing](https://code.visualstudio.com/docs/python/testing) for more details, and [Test Commands](https://code.visualstudio.com/docs/python/testing#_test-commands) for usage. +For all the agents if you want to use another ledger (von-network) other than localhost you will need to change the `genesis-url` config. +For all the agents if you don't want to support revocation you need to remove or comment out the `tails-server-base-url` config. If you want to use a non localhost server then you will need to change the url. -*IMPORTANT*: our pytests include coverage, which will prevent the [debugger from working](https://code.visualstudio.com/docs/python/testing#_debug-tests). One way around this would be to have a `.vscode/settings.json` that says not to use coverage (see above). This will allow you to set breakpoints in the pytest and code under test and use commands such as `Test: Debug Tests in Current File` to start debugging. -*WARNING*: the project configuration found in `pyproject.toml` include performing `ruff` checks when we run `pytest`. Including `ruff` does not play nice with the Testing view. In order to have our pytests discoverable AND available in the Testing view, we create a `.pytest.ini` when we build the devcontainer. This file will not be commited to the repo, nor does it impact `./scripts/run_tests` but it will impact if you manually run the pytest commands locally outside of the devcontainer. Just be aware that the file will stay on your file system after you shutdown the devcontainer. +##### Faber: + - admin api url = http://localhost:9041 + - study the demo to understand the steps to have the agent in the correct state. Make your public dids and schemas, cred-defs, etc. -### ACA-Py +##### Alice: + - admin api url = http://localhost:9011 + - study the demo to get a connection with faber -Above, we added some run/debug configurations, one of which is to run our ACA-Py source code so we can debug it. +##### Endorser + - admin api url = http://localhost:9031 + - This config is useful if you want to develop in an environment that requires endorsement. You can run the demo with `./run_demo faber --endorser-role author` to see all the steps to become and endorser. -In `launch.json` you will see: +##### Author + - admin api url = http://localhost:9021 + - This config is useful if you want to develop in an environment that requires endorsement. You can run the demo with `./run_demo faber --endorser-role author` to see all the steps to become and author. You need to uncomment the configurations for automating the connection to endorser. -``` - { - "name": "Run/Debug ACA-Py", - "type": "python", - "request": "launch", - "module": "aries_cloudagent", - "justMyCode": true, - "args": [ - "start", - "--arg-file=${workspaceRoot}/.vscode/multitenant.yml" - ] - }, -``` + ##### Multitenant-Admin + - admin api url = http://localhost:9051 + - This is for a multitenant environment where you can create multiple tenants with subwallets with one agent. See [Multitenancy](./Multitenancy.md) -To run your ACA-Py code in debug mode, go to the `Run and Debug` view, select "Run/Debug ACA-Py" and click `Start Debugging (F5)`. + ### Try running Faber and Alice at the same time. Add break points and recreate the demo! -This will start your source code as a running ACA-Py instance, all configuration is in the `multitenant.yml` file. This is just a sample of a configuration, and we chose multi-tenancy so we can easily create multiple wallets/agents and have them interact. Note that we are not using a database and are joining the ` http://test.bcovrin.vonx.io` ledger. Feel free to change to a local VON Network (by default, it would be `http://host.docker.internal:9000`) or another ledger. This is purposefully a very simple configuration. +To run your ACA-Py code in debug mode, go to the `Run and Debug` view, select the agent(s) you want to start and click `Start Debugging (F5)`. -Remember those ports we exposed in `devcontainer`? You can open a browser to `http://localhost:9061/api/doc` and see your Admin Console Swagger. Set some breakpoints and hit some endpoints, and start debugging your source code. +This will start your source code as a running ACA-Py instance, all configuration is in the `*.yml` files. This is just a sample of a configuration. Note that we are not using a database and are joining to a local VON Network (by default, it would be `http://localhost:9000`). You could change this or another ledger such as `http://test.bcovrin.vonx.io`. These are purposefully, very simple configurations. For example, open `aries_cloudagent/admin/server.py` and set a breakpoint in `async def status_handler(self, request: web.BaseRequest):`, then call [`GET /status`](http://localhost:9061/api/doc#/server/get_status) in the Admin Console and hit your breakpoint. +### Pytest + +Pytest is installed and almost ready; however, we must build the test list. In the Command Palette, `Test: Refresh Tests` will scan and find the tests. + +See [Python Testing](https://code.visualstudio.com/docs/python/testing) for more details, and [Test Commands](https://code.visualstudio.com/docs/python/testing#_test-commands) for usage. + +*WARNING*: our pytests include coverage, which will prevent the [debugger from working](https://code.visualstudio.com/docs/python/testing#_debug-tests). One way around this would be to have a `.vscode/settings.json` that says not to use coverage (see above). This will allow you to set breakpoints in the pytest and code under test and use commands such as `Test: Debug Tests in Current File` to start debugging. + +*WARNING*: the project configuration found in `pyproject.toml` include performing `ruff` checks when we run `pytest`. Including `ruff` does not play nice with the Testing view. In order to have our pytests discoverable AND available in the Testing view, we create a `.pytest.ini` when we build the devcontainer. This file will not be commited to the repo, nor does it impact `./scripts/run_tests` but it will impact if you manually run the pytest commands locally outside of the devcontainer. Just be aware that the file will stay on your file system after you shutdown the devcontainer. + ## Next Steps At this point, you now have a development environment where you can add pytests, add ACA-Py code and run and debug it all. Be aware there are limitations with `devcontainer` and other docker networks. You may need to adjust other docker-compose files not to start their own networks, and you may need to reference containers using `host.docker.internal`. This isn't a panacea but should get you going in the right direction and provide you with some development tools.