Robot Shop, mapped from the code.
Instana's sample shop: AngularJS behind nginx, with Node, Java, Python, PHP and Go services and RabbitMQ. Kuuhaku read its source at commit 55292e2, with no configuration and no hand-fixing, and found 9 services in JavaScript, Go, Python, PHP and Java, and 12 connections: 11 over HTTP and 1 through a queue. Each one below says how it was found.
Services
Every repo or deployable the scanner found, with how many connections leave it and reach it.
| Service | Stack | Role | Calls | Called by |
|---|---|---|---|---|
web | Docker | consumer | 6 | 0 |
cart | JavaScript · Express | service | 1 | 3 |
payment | Python · Flask | worker | 3 | 1 |
catalogue | JavaScript · Express | service | 0 | 3 |
ratings | PHP · Symfony | service | 1 | 1 |
shipping | Java · Spring Boot | service | 1 | 1 |
user | JavaScript · Express | service | 0 | 2 |
dispatch | Go | worker | 0 | 1 |
load_gen | Python | consumer | 0 | 0 |
Connections
config: the address is written in configuration (an env file, a compose file, a proxy route) and the call is matched to it. inferred: the call's path matches a route of the target and nothing contradicts it. Call sites count the places in the code that make the call.
| From | To | Type | Evidence | Call sites | How it was found |
|---|---|---|---|---|---|
cart | catalogue | HTTP | config | 6 | CATALOGUE_HOST defaults to catalogue, read in the same file |
payment | cart | HTTP | config | 1 | URL worked out at payment.py:116 |
payment | dispatch | queue | inferred | 1 | 1 queue published by payment, consumed by dispatch |
payment | user | HTTP | config | 2 | URL worked out at payment.py:64 |
ratings | catalogue | HTTP | inferred | 1 | its path matches a route of catalogue, which this repo is wired to |
shipping | cart | HTTP | config | 1 | URL worked out at src/main/java/com/instana/robotshop/shipping/Controller.java:136, sent by CartHelper built with it, src/main/java/com/instana/robotshop/shipping/CartHelper.java:40 |
web | cart | HTTP | config | 5 | URL worked out at static/js/controller.js:203, through the /api/cart/ location in default.conf.template |
web | catalogue | HTTP | config | 4 | URL worked out at static/js/controller.js:83, through the /api/catalogue/ location in default.conf.template |
web | payment | HTTP | config | 1 | URL worked out at static/js/controller.js:439, through the /api/payment/ location in default.conf.template |
web | ratings | HTTP | config | 2 | URL worked out at static/js/controller.js:221, through the /api/ratings/ location in default.conf.template |
web | shipping | HTTP | config | 4 | URL worked out at static/js/controller.js:338, through the /api/shipping/ location in default.conf.template |
web | user | HTTP | config | 4 | URL worked out at static/js/controller.js:116, through the /api/user/ location in default.conf.template |
Left for a person
2 items the scanner would not settle on its own and put in the review inbox instead of guessing:
clientinload_gen: base URL assigned at runtime (robot-shop.py:41)requestsinpayment: base URL assigned at runtime (payment.py:84)
Other systems
- OpenTelemetry Demo: 23 services, 30 connections
- Train Ticket: 48 services, 140 connections
- Online Boutique: 12 services, 16 connections
- eShop: 19 services, 31 connections
- Sock Shop: 8 services, 7 connections
- Bank of Anthos: 8 services, 9 connections
- Quarkus Super Heroes: 7 services, 6 connections
- Spring PetClinic Microservices: 7 services, 14 connections
Your own system
Run npx kuuhaku scan . in a folder of repos: it reads the code on your machine and only the graph leaves it. Or connect GitHub or Bitbucket and let the hosted runner scan with a read-only key. The map, a page per repo, a review inbox and a check on every pull request follow. Start free.