{"_id":"@blaccello/tadis-analyzer","_rev":"2-ff230f21fce27e94d7cf0c63ee84306a","name":"@blaccello/tadis-analyzer","dist-tags":{"latest":"0.26.1"},"versions":{"0.26.0":{"name":"@blaccello/tadis-analyzer","version":"0.26.0","author":{"name":"Andreas Blunk, MaibornWolff GmbH"},"license":"Apache-2.0","_id":"@blaccello/tadis-analyzer@0.26.0","maintainers":[{"name":"blaccello","email":"npm@henrich-24.de"}],"homepage":"https://github.com/BlacCello/microservice-visualization#readme","bugs":{"url":"https://github.com/BlacCello/microservice-visualization/issues"},"dist":{"shasum":"56e68dfb6d0a5402f87ff6f186ba8b11702b9e69","tarball":"https://registry.npmjs.org/@blaccello/tadis-analyzer/-/tadis-analyzer-0.26.0.tgz","fileCount":3,"integrity":"sha512-Q/e5Z/ynBeHiORzPwHFAOOp3u0eLWKuuixZV5+EirSRJWXuPLDD45c9ICwKa5aM61AcVdew/dPXbgTJCG7naNg==","signatures":[{"sig":"MEQCIHiGgvDRetPlz0onCNSFhFUpkyK36ueUGW5gHrZjoQafAiBU2kB6HkG88APCqgm9RIgizzQYG1EHwZC1VTTWDJdjSQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blaccello%2ftadis-analyzer@0.26.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":22341},"jest":{"rootDir":"src","testMatch":["**/*.test.ts"],"transform":{"^.+\\.(t|j)s$":"ts-jest"},"testEnvironment":"node","coverageDirectory":"../coverage","moduleFileExtensions":["js","json","ts"]},"main":"build/src/lib.js","types":"build/src/lib.d.ts","gitHead":"4e392d5bc0c8cfb0c147e8b5ca9240328dbf98d2","scripts":{"lint":"eslint \"{src,apps,libs,test}/**/*.ts\"","test":"jest --runInBand","build":"tsc","start":"ts-node -r tsconfig-paths/register src/app/default/main.ts","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","lint-fix":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test:cov":"jest --coverage","test:e2e":"jest --config ./test/jest-e2e.json","start:dev":"nodemon","docker-run":"node docker-run.js","start:prod":"node build/src/app/default/main.js","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:watch":"jest --watch","start:debug":"nodemon --config nodemon-debug.json","test-failed":"jest -f --runInBand","code-pattern":"ts-node -r tsconfig-paths/register src/app/code-pattern/main.ts","docker-build":"node docker-build.js","test:verbose":"jest --verbose","docker-publish":"node docker-publish.js"},"_npmUser":{"name":"blaccello","email":"npm@henrich-24.de"},"repository":{"url":"git+https://github.com/BlacCello/microservice-visualization.git","type":"git"},"_npmVersion":"10.9.2","description":"generic analyzer tool for architecture discovery","directories":{},"_nodeVersion":"22.15.0","dependencies":{"joi":"^17.6.3","rxjs":"^7.5.5","axios":"^0.27.2","immer":"^9.0.15","dotenv":"^16.0.1","lodash":"^4.17.11","rimraf":"^3.0.2","@nestjs/core":"^9.0.5","@nestjs/axios":"^0.1.0","@nestjs/common":"^9.0.5","reflect-metadata":"^0.1.13","@kubernetes/client-node":"^0.22.2","@nestjs/platform-express":"^9.0.5"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","eslint":"^8.20.0","nodemon":"^3.0.1","ts-jest":"^28.0.7","ts-node":"^10.9.1","prettier":"^2.7.1","supertest":"^6.2.4","@types/joi":"^14.3.4","typescript":"^4.7.4","@nestjs/cli":"^9.0.0","@types/jest":"^28.1.6","@types/node":"^20.5.7","@types/lodash":"^4.14.182","@types/express":"^4.17.13","tsconfig-paths":"^4.0.0","@nestjs/testing":"^9.0.5","@types/supertest":"^2.0.12","@nestjs/schematics":"^9.0.1","source-map-support":"^0.5.21","eslint-config-prettier":"^8.5.0","@typescript-eslint/parser":"^5.30.7","@typescript-eslint/eslint-plugin":"^5.30.7"},"_npmOperationalInternal":{"tmp":"tmp/tadis-analyzer_0.26.0_1747131366393_0.044170404015876574","host":"s3://npm-registry-packages-npm-production"}},"0.26.1":{"name":"@blaccello/tadis-analyzer","repository":{"type":"git","url":"git+https://github.com/BlacCello/microservice-visualization.git"},"version":"0.26.1","description":"generic analyzer tool for architecture discovery","main":"build/src/lib.js","types":"build/src/lib.d.ts","license":"Apache-2.0","author":{"name":"Andreas Blunk, MaibornWolff GmbH"},"scripts":{"build":"tsc","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","start":"ts-node -r tsconfig-paths/register src/app/default/main.ts","start:dev":"nodemon","start:debug":"nodemon --config nodemon-debug.json","start:prod":"node build/src/app/default/main.js","code-pattern":"ts-node -r tsconfig-paths/register src/app/code-pattern/main.ts","lint":"eslint \"{src,apps,libs,test}/**/*.ts\"","lint-fix":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest --runInBand","test-failed":"jest -f --runInBand","test:verbose":"jest --verbose","test:watch":"jest --watch","test:cov":"jest --coverage","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:e2e":"jest --config ./test/jest-e2e.json","docker-build":"node docker-build.js","docker-run":"node docker-run.js","docker-publish":"node docker-publish.js"},"dependencies":{"@kubernetes/client-node":"^0.22.2","@nestjs/axios":"^0.1.0","@nestjs/common":"^9.0.5","@nestjs/core":"^9.0.5","@nestjs/platform-express":"^9.0.5","axios":"^0.27.2","dotenv":"^16.0.1","immer":"^9.0.15","joi":"^17.6.3","lodash":"^4.17.11","reflect-metadata":"^0.1.13","rimraf":"^3.0.2","rxjs":"^7.5.5"},"devDependencies":{"@nestjs/cli":"^9.0.0","@nestjs/schematics":"^9.0.1","@nestjs/testing":"^9.0.5","@types/express":"^4.17.13","@types/jest":"^28.1.6","@types/joi":"^14.3.4","@types/lodash":"^4.14.182","@types/node":"^20.5.7","@types/supertest":"^2.0.12","@typescript-eslint/eslint-plugin":"^5.30.7","@typescript-eslint/parser":"^5.30.7","eslint":"^8.20.0","eslint-config-prettier":"^8.5.0","jest":"^28.1.3","nodemon":"^3.0.1","prettier":"^2.7.1","source-map-support":"^0.5.21","supertest":"^6.2.4","ts-jest":"^28.0.7","ts-node":"^10.9.1","tsconfig-paths":"^4.0.0","typescript":"^4.7.4"},"jest":{"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testMatch":["**/*.test.ts"],"transform":{"^.+\\.(t|j)s$":"ts-jest"},"coverageDirectory":"../coverage","testEnvironment":"node"},"_id":"@blaccello/tadis-analyzer@0.26.1","gitHead":"74e098f3f4f4b8f64a3a16d6fb9e733836b17e88","bugs":{"url":"https://github.com/BlacCello/microservice-visualization/issues"},"homepage":"https://github.com/BlacCello/microservice-visualization#readme","_nodeVersion":"22.15.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-sTFmj0xUdaFd8X7aEE/BE9GX6wcU8GTOfeE2BomWW+E8idMX7DLh8YDy3uRRyRupWDp7A2NBPeIcdAQyCcGXjg==","shasum":"118766f7542b7af6fe60a705bb2933120d9d63af","tarball":"https://registry.npmjs.org/@blaccello/tadis-analyzer/-/tadis-analyzer-0.26.1.tgz","fileCount":3,"unpackedSize":22341,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blaccello%2ftadis-analyzer@0.26.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGC6qIa7s2W05Y/PYV5RX4tmQix2I7jwankJuhYWU2gtAiEA23AbXilZ/wuWFES/pb0FM/4hs6XaNhGtm7YlHxJZuXQ="}]},"_npmUser":{"name":"blaccello","email":"npm@henrich-24.de"},"directories":{},"maintainers":[{"name":"blaccello","email":"npm@henrich-24.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tadis-analyzer_0.26.1_1747132282528_0.5239133689160949"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-13T10:16:06.313Z","modified":"2025-05-13T10:31:23.099Z","0.26.0":"2025-05-13T10:16:06.568Z","0.26.1":"2025-05-13T10:31:22.725Z"},"bugs":{"url":"https://github.com/BlacCello/microservice-visualization/issues"},"author":{"name":"Andreas Blunk, MaibornWolff GmbH"},"license":"Apache-2.0","homepage":"https://github.com/BlacCello/microservice-visualization#readme","repository":{"type":"git","url":"git+https://github.com/BlacCello/microservice-visualization.git"},"description":"generic analyzer tool for architecture discovery","maintainers":[{"name":"blaccello","email":"npm@henrich-24.de"}],"readme":"# tadis-analyzer\n\ntadis-analyzer can discover the architecture of a microservice system by collecting information about the system from different sources. These sources include infrastructure services, e.g. Kubernetes and RabbitMQ, which provide real-time information, and Git repositories, which add information from static source code analysis.\n\nTADIS is designed as a DEV tool that a gives a team an overview of the services and their dependencies when planning further development of the system. It allows to customize the analysis in order to visualize system-specific architecture aspects. TADIS is not intended for system performance analysis.\n\nThe analyzer is provided as a stand-alone microservice as well as a NPM package which can be integrated into a self-made microservice. Either way, it provides a generic REST controller with the following endpoints:\n* `/collect/system` uses a CollectorService to create a graph of a microservice system by using different transformers. A small example is given in [here for Kubernetes and RabbitMQ](src/system-assemblers/kubernetes-rabbitmq/KubernetesRabbitMqAssembler.service.ts). A larger example is given in the [customized-analyzer-example](../customized-analyzer-example/README.md). The available transformers are described in the next section.\n* `/collect/source` triggers a source code import for all microservices. The CollectorService provides a list of available microservices. For each microservice, an import of its Git repository is triggered by using the [GitStorage service](src/git/GitStorage.service.ts).\n* `/source/store/repository/:repositoryName` allows to trigger the import of a specific microservice repository.\n* `/source/status` gives a info object of the imported repositories.\n\n## Configuration\n\nEnvironment Variables:\n- PORT: defines the PORT of the REST endpoints\n- SOURCE_FOLDER: defines the folder where source code is stored on import\n- GIT_BASE_URLS: is a comma-separated list of base URLs that are inspected for microservice repository locations.\n\n## Usage\n\n* install: `npm install`\n* run: `npm run start`\n* build Docker image: `npm run docker-build`\n* run Docker image: `npm run docker-run`\n\n## Getting Started\n\nPlease see [custom-example-analyzer](../custom-example-analyzer/README.md).\n\n## Transformers\n\nTransformers are used by a collector to assemble a system by collecting information from different sources. Each transformer gets an input system and transforms the system into an output system.\n\nA system uses concepts of microservice systems which are [defined by this model](src/model/ms.ts). The system model is a typed extension of a [generic model](src/model/core.ts).\n\nThe following transformers are available out-of-the-box:\n\n- Kubernetes Transformers\n  - MicroservicesFromKubernetesCreator\n  - EnvDefinitionFromPodDecorator\n  - LabelsFromDeploymentDecorator\n- Java Transformers\n  - FeignClientAnnotationAnalyzer\n  - JavaAnnotationAnalyzer\n- RabbitMQ Transformers\n  - RabbitMqBindingsFromApiAnalyzer\n  - ExchangesFromEnvPayloadCreator\n  - OutgoingExchangesFromSourceCreator\n  - MicroserviceWithOutgoingExchangeMerger\n- Common Transformers\n  - SourceLocationDecorator\n  - StaticNodeFilter\n  - SubSystemFromPayloadTransformer\n- Source Pattern Analyzer\n\nThe transformers and their configuration options are described in next sections.\n\n### Kubernetes Transformers\n\nEnvironment Variables:\n- KUBERNETES_NAMESPACE: All Kubernetes transformers use this fixed namespace.\n\nAssumptions in each transformer:\n- `pod.metadata.name` starts with a microservice name which is followed by minus character, e.g. `microservicename-8648fc44bb-5qnm8`\n- this assumption is violated if you use minus in your microservice names and if you have multiple microservices beginning with the same name\n\n#### MicroservicesFromKubernetesCreator\n\n- gets all services and pods from the Kubernetes namespace\n- creates a microservice for each service that also has a pod\n- assumptions:\n  - `service.metadata.name` is a microservice name\n\n#### EnvDefinitionFromPodDecorator\n\n- gets all pods from the Kubernetes namespace\n- adds attribute `env` of each `container` in `pod.spec.containers` to the payload of the microservice\n\n#### LabelsFromDeploymentDecorator\n\n- gets all deployments from the Kubernetes namespace\n- adds attribute `labels` from `deployment.metadata.labels` to the payload of the microservice\n\n### Java Transformers\n\n#### FeignClientAnnotationAnalyzer\n\n- searches in the source code of each microservice for `*.java` files for the pattern `/@FeignClient\\s*\\(\\s*(value\\s*=)?\\s*\"([\\w-]+)\"/`\n- for each value creates a SyncDataFlow between the current microservice and the target microservice referred to in value\n\n#### JavaAnnotationAnalyzer (non-MSA)\n\n- an attempt to generalize analyzers for Java annotations\n- the transform method is passed an annotation to search for and actions defined as mapping of annotation elements to graph extensions\n- [see source code](sources/tadis-analyzer/src/java/JavaAnnotationAnalyzer.ts) for details\n\n````typescript\ntransform(system: System, annotation: string, elementMappings: ElementMapping[]): Promise<System> { ... }\n````\n\n### RabbitMQ Transformers\n\n#### RabbitMqBindingsFromApiAnalyzer\n\n- uses the [RabbitMQ Management Plugin](https://www.rabbitmq.com/management.html)\n- gets all queue to exchange bindings for each queue via `/api/queues/<vhost>/<queueName>/bindings/` (only supports vhost `/`)\n- if queue name equals `<microservice-name>.<text>` for any existing microservice\n  - then an AsyncEventFlow is created between the exchange and microservice\n  - else a MessageQueue is created and used instead of the microservice\n\nEnvironment Variables:\n- RABBIT_USER and RABBIT_PASSWORD for use in basic auth\n- RABBIT_URL: base URL to RabbitMQ Management API\n\n#### ExchangesFromEnvPayloadCreator\n\n- searches in each node payload for an `env` attribute\n- the `env` attribute must be of type EnvEntry[]\n\n````typescript\ntype EnvEntry = {\n  name: string,\n  value: string\n}\n````\n\n- for each `env.name` that contains the string `EXCHANGE`\n  - if the `env.name` also contains the string `OUTGOING` then an AsyncEventFlow is added between the current microservice and the exchange defined in `env.value`\n  - if instead the `env.name` also contains the string `INCOMING`then an AsyncEventFlow is added from the exchange towards the current microservice\n\n#### OutgoingExchangesFromSourceCreator\n\n- searches in the source code of each microservice for `.java` files that also have `send` in their filename\n- searches for variable assignments matching the pattern `/exchange[\\w]*[\\s]*=\\s*\"(\\w+)\"/ig` where the expression identifies the exchange that is used for sending messages.\n- for each sending exchange found, creates an AsyncEventFlow between the current microservice and the exchange\n\n#### MicroserviceWithOutgoingExchangeMerger\n\n- searches for microservice nodes having just one outgoing exchange whose name equals the name of the microservice node\n- merges each such exchange into the microservice node, including payload and metadata, and adds the payload `reduced=true` to the node\n\n### Common Transformers (not microservice system specific)\n\n#### SourceLocationDecorator\n\nAdds payload `sourceLocation` to each microservice where source code was fetched via Git.\n\n#### StaticNodeFilter\n\nFilters nodes from a flat system.\n\nEnvironment Variables:\n- EXCLUDED_NODE_NAMES\n  - comma-separated list of names\n  - regular expressions may be used\n  - example: dummy.*, foo\n\n#### SubSystemFromPayloadTransformer\n\nUse this transformer when you have a flat system where some nodes have a payload defining their association to a sub-system and you want the system to be transformed to a system of sub-systems. This transformer creates new sub-system nodes and moves each node to its sub-system node.\n\nHow sub-system information is to be extracted from a nodes payload must be specified when calling the transformer.\n\n[see SubSystemTransformer.ts](sources/tadis-analyzer/src/msa/common/SubSystemTransformer.ts)\n\n## License\n\n[Apache License, Version 2.0](LICENSE)\n\nCopyright 2017-2022 Andreas Blunk, MaibornWolff GmbH\n","readmeFilename":"README.md"}