{"id":15867336,"url":"https://github.com/joatmon08/expense-report","last_synced_at":"2025-03-16T02:31:20.443Z","repository":{"id":42622482,"uuid":"239602568","full_name":"joatmon08/expense-report","owner":"joatmon08","description":"A demo with Spring and .NET applications that use Consul's service mesh. Includes Vault \u0026 Kubernetes.","archived":false,"fork":false,"pushed_at":"2024-04-12T22:56:41.000Z","size":13859,"stargazers_count":5,"open_issues_count":4,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-27T04:47:47.139Z","etag":null,"topics":["consul","docker","dotnet","kubernetes","service-mesh","spring","vault"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joatmon08.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-10T20:07:51.000Z","updated_at":"2023-03-23T07:40:14.000Z","dependencies_parsed_at":"2024-10-06T00:00:49.327Z","dependency_job_id":"a5b9f700-1e6e-4541-8775-8588382fac1e","html_url":"https://github.com/joatmon08/expense-report","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joatmon08%2Fexpense-report","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joatmon08%2Fexpense-report/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joatmon08%2Fexpense-report/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joatmon08%2Fexpense-report/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joatmon08","download_url":"https://codeload.github.com/joatmon08/expense-report/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243801678,"owners_count":20350108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consul","docker","dotnet","kubernetes","service-mesh","spring","vault"],"created_at":"2024-10-06T00:00:25.987Z","updated_at":"2025-03-16T02:31:17.185Z","avatar_url":"https://github.com/joatmon08.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Expense Report\n\nA set of .NET Core and Java Spring Boot services that records expenses\nand returns a report for a given trip identifier.\n\n## What it does\n\nExpense Report uses Consul for service mesh, application configuration,\nand feature toggling capabilities.\n\nFor multiple frameworks, Consul Connect provides service mesh capabilities\nthat enable a consistent method of configuring:\n\n* Service Discovery\n* Network Policy (via Consul intentions)\n* Load balancing\n* Additional Tracing Metadata\n* Circuit Breaking (AKA Outlier Detection)\n\n## Expense Report Application\n\nThe report application connects to the expense application, which retrieves information\nfrom a database. You'll find two versions of the expense application, one in .NET and one in Java.\n\n![How Expense Report Works](./image/diagram.png)\n\nBelow are the most useful endpoints for the `expense` service:\n\n- GET `/api/expense`: Get a list of expenses\n- POST `/api/expense`: Create a new expense. See schema under `example/expense.json`.\n\nJava defaults to `:8080` and .NET Core\ndefaults to `:5001`.\n\nBelow are the most useful endpoints for the `report` service:\n\n- GET `/api/report/expense/version`: Gets the version of the expense application for debugging\n- GET `/api/report/trip/${trip_id}`: Gets a list of expenses for a given trip.\n\n`${trip_id}` denotes the trip identifier passed in the body of the expense item\ncreated in the `POST` method to `expense`. Since the `report` application is\ncurrently only available in .NET Core, it runs by default on port `:5002`.\n## Kubernetes\n\n![How Expense Report Works](./image/kubernetes.png)\n\n### Prerequisites\n\n- Kubernetes. The configurations use a cluster set up in GKE as per the `/terraform` directory.\nYou can use the Terraform to create a Kubernetes cluster for all of the applications.\n\n- [Locust](https://locust.io/) to mimic user traffic.\n\n- Consul 1.11+\n\n- Vault 1.9+\n\n- Terraform 1.0+. For creating cluster and configuring Vault.\n\n- Azure\n  - Create a service principal with owner access to the subscription.\n\n- Terraform Cloud account and three workspaces\n\n    - `infrastructure`: working directory under `terraform/infrastructure`\n       - Add Azure credentials\n       - `prefix` variable for identification\n\n    - `helm`: working directory under `terraform/helm`\n       - `prefix` variable for identification\n       - `vault_token` variable for logging into Vault\n       - `tfc_workspace` variable referencing `infrastructure`\n       - `tfc_organization` variable referencing your TFC organization\n\n    - `vault`: working directory under `terraform/vault`\n       - `tfc_workspace` variable referencing `helm`\n       - `tfc_organization` variable referencing your TFC organization\n\n### Create resources\n\n- Run `terraform apply` for `infrastructure` workspace\n- Run `terraform apply` for `helm` workspace\n- Run `terraform apply` for `vault` workspace\n\n### Deploy everything to Kubernetes\n\nDeploy tracing and gateway.\n\n```shell\nbash scripts/kubernetes.sh tracing setup\n```\n\nDeploy databases. Enter `yes` to continue.\n\n```shell\nbash scripts/kubernetes.sh databases setup\n```\n\nDeploy expense service.\n\n```shell\nbash scripts/kubernetes.sh expense setup\n```\n\nDeploy report service.\n\n```shell\nbash scripts/kubernetes.sh report setup\n```\n\nDeploy split traffic configuration.\n\n```shell\nbash scripts/kubernetes.sh split setup\n```\n\nDeploy route traffic configuration.\n\n```shell\nbash scripts/kubernetes.sh route setup\n```\n\n### Cleanup\n\nRemove everything from the Kubernetes cluster.\n\n```shell\nbash scripts/kubernetes.sh clean\n```\n\nDelete everything from the `vault` TFC workspace.\n\nDelete everything from the `helm` TFC workspace.\n\nDelete everything from the `infrastructure` TFC workspace.\n\n## Docker-Compose\n\nThis is for local demonstration purposes only. The Consul server\nhas a different configuration than what you would expect for production!\nIt does not use Vault for dynamic secrets.\n### Prerequisites\n\n* Docker\n* docker-compose\n\n### Startup\n\nTo start, bring up the Consul server, MySQL database, Microsoft SQL\nServer database, Jaeger for tracing,\nthe expense services in .NET and Java, and the report service\nin .NET.\n\n```shell\nbash scripts/compose.sh all\n```\n\nThis will not only bring up the stack but add the application configuration\nfor the `expense` service.\n\n![Consul UI after bringing up main stack](./image/makeall.png)\n\nOpen Jaeger on http://localhost:16686 and Consul on http://localhost:8500.\n\n### Service Networking with Consul Service Mesh\n\nTo try out:\n\n* Service discovery\n* Network policy\n* Load balancing\n* Additional tracing metadata\n\n#### Traffic Splitting\n\nWhen you start the demo by default, it sets a `service-splitter`\nand `service-router` that divides traffic equally between the Java\nand .NET applications.\n\nTest this by calling the version API endpoint. You'll notice half the\nresponses are `6.0` (.NET) and `0.0.1-SNAPSHOT` (Java). This means\nthat the proxy is separating traffic between the two service\ninstances for expense.\n\n```shell\nbash scripts/compose.sh split test\n```\n\nYou can adjust `compose_configs/traffic_config/expense-splitter.hcl`\nwith the ratio of your choice to test this further. Re-apply\nthe configuration with the following command:\n\n```shell\nbash scripts/compose.sh split setup\n```\n\n#### Route Based on Header\n\nSometimes, you want to test an application but only\nif you pass a specific header. You can set a `service-resolver`\nwith a `service-router`.\n\nSet them up using the following command.\n\n```shell\nbash scripts/compose.sh route setup\n```\n\nTest this by going into the report proxy's container\nand passing a header. You'll notice that the response\nroutes to `0.0.1-SNAPSHOT` (Java) if you set the header\nor `6.0` (.NET) by default.\n\n```shell\nbash scripts/compose.sh route test\n```\n\n#### Circuit Breaking\n\nTo try __circuit breaking__ (outlier detection in Envoy), note that it the\nconfiguration requires an unsupported Consul escape hatch override. It cannot\nhave any service resolver or splitter configuration.\n\nStop the Microsoft SQL Server database. This will fail calls to the .NET Core\n`expense` service. As a result, circuit breaker will trip in the `report`\nservice and route all traffic to the Java `expense` service.\n\nIssue the command for testing.\n\n```shell\nbash scripts/compose.sh circuit_break test\n```\n\nAfter you are done, reset the circuit breaker.\n\n```shell\nbash scripts/compose.sh circuit_break reset\n```\n\n### Clean Up\n\nRemove everything using a command.\n\n```shell\nbash scripts/compose.sh clean\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoatmon08%2Fexpense-report","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoatmon08%2Fexpense-report","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoatmon08%2Fexpense-report/lists"}