{"id":14977596,"url":"https://github.com/cloudogu/command-bus","last_synced_at":"2026-03-06T07:03:14.863Z","repository":{"id":41238681,"uuid":"98885701","full_name":"cloudogu/command-bus","owner":"cloudogu","description":"Java implementation of the Command-Bus pattern for Spring and CDI","archived":false,"fork":false,"pushed_at":"2025-09-12T17:50:34.000Z","size":226,"stargazers_count":47,"open_issues_count":1,"forks_count":10,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2025-10-28T04:32:32.960Z","etag":null,"topics":["cdi","command-bus","java","logging","prometheus","spring"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudogu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-07-31T12:18:10.000Z","updated_at":"2025-09-20T13:11:14.000Z","dependencies_parsed_at":"2024-09-18T22:05:39.900Z","dependency_job_id":null,"html_url":"https://github.com/cloudogu/command-bus","commit_stats":{"total_commits":113,"total_committers":11,"mean_commits":"10.272727272727273","dds":0.6371681415929203,"last_synced_commit":"ac0445b11b8a2962dbd2698f3abd53d82f46b71a"},"previous_names":["triologygmbh/command-bus"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/cloudogu/command-bus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudogu%2Fcommand-bus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudogu%2Fcommand-bus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudogu%2Fcommand-bus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudogu%2Fcommand-bus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudogu","download_url":"https://codeload.github.com/cloudogu/command-bus/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudogu%2Fcommand-bus/sbom","scorecard":{"id":293139,"data":{"date":"2025-08-11","repo":{"name":"github.com/cloudogu/command-bus","commit":"ac0445b11b8a2962dbd2698f3abd53d82f46b71a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 4/12 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: .mvn/wrapper/maven-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'develop'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T18:48:29.656Z","repository_id":41238681,"created_at":"2025-08-17T18:48:29.656Z","updated_at":"2025-08-17T18:48:29.656Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30164902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T04:43:31.446Z","status":"ssl_error","status_checked_at":"2026-03-06T04:40:30.133Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cdi","command-bus","java","logging","prometheus","spring"],"created_at":"2024-09-24T13:55:57.910Z","updated_at":"2026-03-06T07:03:14.834Z","avatar_url":"https://github.com/cloudogu.png","language":"Java","readme":"# command-bus\n[![Build Status](https://oss.cloudogu.com/jenkins/buildStatus/icon?job=cloudogu-github/command-bus/master)](https://oss.cloudogu.com/jenkins/blue/organizations/jenkins/cloudogu-github%2Fcommand-bus/branches/)\n[![Quality Gates](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent)\n[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent\u0026metric=sqale_index)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent)\n\nCDI/Spring enabled Java Command-Bus\n\n# Table of contents\n\u003c!-- Update with `doctoc --notitle README.md`. See https://github.com/thlorenz/doctoc --\u003e\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n  - [Concepts](#concepts)\n  - [Usage](#usage)\n    - [Dependency for CDI](#dependency-for-cdi)\n    - [Dependency for Spring](#dependency-for-spring)\n    - [API](#api)\n    - [Internals](#internals)\n  - [Command Bus Decorators](#command-bus-decorators)\n    - [Prometheus metric decorators](#prometheus-metric-decorators)\n      - [PrometheusMetricsCountingCommandBus](#prometheusmetricscountingcommandbus)\n      - [PrometheusMetricsTimingCommandBus](#prometheusmetricstimingcommandbus)\n    - [Micrometer metric decorators](#micrometer-metric-decorators)\n      - [MicrometerCountingCommandBus](#micrometercountingcommandbus)\n      - [MicrometerTimingCommandBus](#micrometertimingcommandbus)\n    - [Validating command bus](#validating-command-bus)\n  - [Return values](#return-values)\n- [Examples](#examples)\n  - [Spring](#spring)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Concepts\n\n* [`Command`](command-bus-core/src/main/java/com/cloudogu/cb/Command.java) - Marker Interface\n* [`CommandHandler`](command-bus-core/src/main/java/com/cloudogu/cb/CommandHandler.java) - One Implementation per `Command`. Provides `handle(CommandImplementation)` Method.\n* [`CommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/CommandBus.java) - Finds and calls the `CommandHandler` for each `Command`.\n* `CommandBus` can be decorated, in order to implement cross-cutting concerns, such as logging, transaction handling, validation, autorization, metrics etc.\n\n## Usage\n\nAdd the [latest stable version of command-bus](http://search.maven.org/#search|gav|1|g%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-cdi%22) to the dependency management tool of your choice.\nYou can also get snapshot versions from our [snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/com/cloudogu/cb/) (for the most recent commit on develop branch).\nTo do so, add the following repo to your `pom.xml` or `settings.xml`:\n```xml\n\u003crepository\u003e\n    \u003cid\u003esnapshots-repo\u003c/id\u003e\n    \u003curl\u003ehttps://oss.sonatype.org/content/repositories/snapshots\u003c/url\u003e\n    \u003creleases\u003e\u003cenabled\u003efalse\u003c/enabled\u003e\u003c/releases\u003e\n    \u003csnapshots\u003e\u003cenabled\u003etrue\u003c/enabled\u003e\u003c/snapshots\u003e\n\u003c/repository\u003e\n```\n\nThere are different versions of command-bus for either CDI or spring.\n\n### Dependency for CDI\n\n```XML\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.cloudogu.cb\u003c/groupId\u003e\n    \u003cartifactId\u003ecommand-bus-cdi\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.cloudogu.cb/command-bus-cdi.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-cdi%22)\n\n\n### Dependency for Spring\n\n```XML\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.cloudogu.cb\u003c/groupId\u003e\n    \u003cartifactId\u003ecommand-bus-spring\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n[![Maven Central](https://img.shields.io/maven-central/v/com.cloudogu.cb/command-bus-spring.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-spring%22)\n\n### API\n\n* Bootstrapping\n  * CDI: Having the `command-bus-cdi` dependency on the classpath triggers the CDI extension\n  * Spring: All CommandHandlers must be within the application context (e.g. `@Component` in spring boot)\n* Implement your [`Command`](command-bus-core/src/main/java/com/cloudogu/cb/Command.java)s and the logic in appropriate \n  [`CommandHandler`](command-bus-core/src/main/java/com/cloudogu/cb/CommandHandler.java)s. \n* You can now just inject the [`CommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/CommandBus.java) and pass your\n `Commands` to its `execute()` method. It will automatically pass it to the appropriate handler.\n* Examples:\n  * [`CDIITCase`](command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CDIITCase.java)\n  * [`SpringITCase`](command-bus-spring/src/test/java/com/cloudogu/cb/spring/SpringITCase.java)\n* If you want to decorate your command bus (for logging, metrics, etc.), a factory/producer for the `CommandBus` is the\n  central place where decorators can be instantiated.\n  It brings together your `CommandBus` (e.g. [`CDICommandBus`](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDICommandBus.java),\n  [`SpringCommandBus`](command-bus-spring/src/main/java/com/cloudogu/cb/spring/SpringCommandBus.java)) with decorators \n  (see [bellow](#command-bus-decorators)).\n  Example `CommandBusFactory`s:\n  * [CDI](command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CommandBusFactory.java)\n  * [Spring](command-bus-spring/src/test/java/com/cloudogu/cb/spring/CommandBusFactory.java)\n   \n### Internals\n  \nThe `CommandHandler`s for CDI and Spring both use a `Registry` ([CDI](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/Registry.java) / \n[Spring](command-bus-spring/src/main/java/com/cloudogu/cb/spring/Registry.java)) to store `Command`s and \n`CommandHandler`s. Difference:\n* CDI: The [`CDIExtension`](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDIExtension.java) finds all `Command`s \n    and `CommandHandler`s and puts them on the `Registry`.\n* Spring: The `Registry` itself gets all `Command`s and `CommandHandler`s from the application context.\n\n## Command Bus Decorators\n\nFirst example is the logging decorator ([`LoggingCommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/decorator/LoggingCommandBus.java)) that logs entering and leaving (including time of execution) of `CommandHandler`s.\n\n### Prometheus metric decorators\nThe Command Bus provides two Prometheus metrics decorators. More information on Prometheus can be found on the\nproject's [website](https://prometheus.io).\nIn order to use them, make sure to provide the `io.prometheus:simpleclient` dependency on the classpath.\n\n#### PrometheusMetricsCountingCommandBus\nThe `PrometheusMetricsCountingCommandBus` counts every executed command, using a Prometheus Counter. \nThe counter to be used must be provided as a constructor parameter. For each type of command (i.e. it's class name) a \nlabel is created automatically.\n\n#### PrometheusMetricsTimingCommandBus\nThe `PrometheusMetricsTimingCommandBus` captures the time a command's execution takes and provides the metric as a \nPrometheus Histogram. Similarly to the `PrometheusMetricsCountingCommandBus`, the Histogram needs to be provided as a \nconstructor parameter.\n\n### Micrometer metric decorators\nThe Command Bus provides two Micrometer metrics decorators. More information on Micrometer can be found on the\nproject's [website](https://micrometer.io).\nIn order to use them, make sure to provide a micrometer registry implementation such as prometheus `io.micrometer:micrometer-registry-prometheus`.\n\nSee [cloudogu/springboot-micrometer-demo-command-bus](cloudogu/springboot-micrometer-demo-command-bus) for a complete example.\n\n#### MicrometerCountingCommandBus\n\nThe `MicrometerCountingCommandBus` counts every executed command, using a Micrometer Counter e.g.:\n\n```java\nCommandBus commandBusImpl = ...;\nMicrometerCountingCommandBus commandBus = new MicrometerCountingCommandBus(commandBusImpl, \n  commandClass -\u003e Counter.builder(\"command.counter\")\n    .description(\"command execution counter\")\n    .tags(\"command\", commandClass.getSimpleName())\n    .register(Metrics.globalRegistry)\n);\n```\n\n#### MicrometerTimingCommandBus\n\nThe `MicrometerTimingCommandBus` measures the elapsed time for every command execution by using a Micrometer a Micrometer Counter e.g.:\n\n```java\nCommandBus commandBusImpl = ...;\nMicrometerTimingCommandBus commandBus = new MicrometerTimingCommandBus(commandBusImpl, \n  commandClass -\u003e Timer.builder(\"command.timer\")\n    .description(\"command execution timer\")\n    .tags(\"command\", commandClass.getSimpleName())\n    .register(Metrics.globalRegistry)\n);\n```\n\n### Validating command bus\nThe `ValidatingCommandBus` uses the `javax.validation` API to validate the command, before execution.\nThe `CommandBus` will throw an `ConstraintViolationException`, if the command violates validation rules.\nMake sure to provide `javax.validation` implementation at runtime, such as `org.hibernate:hibernate-validator`. \n\n```java\npublic class NotifyCommand implements Command\u003cVoid\u003e {\n  @Email\n  private String email;\n\n  public SampleCommand(String email) {\n    this.email = email;\n  }\n}\n\nCommandBus commandBusImpl = ...;\nValidatorFactory factory = Validation.buildDefaultValidatorFactory();\nValidatingCommandBus commandBus = new ValidatingCommandBus(commandBusImpl, factory.getValidator());\nNotifyCommand command = createNotifyCommand();\ncommandBus.execute(command);\n```\n\n## Return values\n\n* `Command`s can specify return values. See [`HelloCommand`](command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommand.java) and  [`com.cloudogu.cb.EchoCommandHandler`](command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommandHandler.java) for example.\n* If you don't want a return value, use `Void`. See [`ByeCommand`](command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommand.java) and  [`ByeCommandHandler`](command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommandHandler.java) for example.\n\n# Examples\n\n## Spring\n\n* [cloudogu/smeagol](https://github.com/cloudogu/smeagol)\n* [cloudogu/springboot-micrometer-demo-command-bus](https://github.com/cloudogu/springboot-micrometer-demo-command-bus)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudogu%2Fcommand-bus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudogu%2Fcommand-bus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudogu%2Fcommand-bus/lists"}