{"id":36418287,"url":"https://github.com/bpm-crafters/process-engine-worker","last_synced_at":"2026-03-05T00:10:55.134Z","repository":{"id":252932893,"uuid":"793549694","full_name":"bpm-crafters/process-engine-worker","owner":"bpm-crafters","description":"Annotation-based Service Task worker for Process Engine API for Spring Boot","archived":false,"fork":false,"pushed_at":"2026-02-26T07:54:29.000Z","size":1266,"stargazers_count":12,"open_issues_count":15,"forks_count":2,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2026-02-26T12:56:02.575Z","etag":null,"topics":["kotlin","process-engine","process-engine-api","worker"],"latest_commit_sha":null,"homepage":"https://bpm-crafters.github.io/process-engine-api-docs/snapshot/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bpm-crafters.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-29T12:38:00.000Z","updated_at":"2026-02-16T13:36:27.000Z","dependencies_parsed_at":"2024-09-09T09:55:31.972Z","dependency_job_id":"9bdcfafd-c7dc-4564-b8e3-2bae874fd102","html_url":"https://github.com/bpm-crafters/process-engine-worker","commit_stats":null,"previous_names":["bpm-crafters/process-engine-worker"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/bpm-crafters/process-engine-worker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpm-crafters%2Fprocess-engine-worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpm-crafters%2Fprocess-engine-worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpm-crafters%2Fprocess-engine-worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpm-crafters%2Fprocess-engine-worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpm-crafters","download_url":"https://codeload.github.com/bpm-crafters/process-engine-worker/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpm-crafters%2Fprocess-engine-worker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30102201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T23:59:36.199Z","status":"ssl_error","status_checked_at":"2026-03-04T23:56:48.556Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["kotlin","process-engine","process-engine-api","worker"],"created_at":"2026-01-11T17:01:07.087Z","updated_at":"2026-03-05T00:10:55.092Z","avatar_url":"https://github.com/bpm-crafters.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Process Engine API Worker\n\n\n[![stable](https://img.shields.io/badge/lifecycle-STABLE-green.svg)](https://github.com/holisticon#open-source-lifecycle)\n[![Development branches](https://github.com/bpm-crafters/process-engine-worker/actions/workflows/development.yml/badge.svg)](https://github.com/bpm-crafters/process-engine-worker/actions/workflows/development.yml)\n[![Maven Central Version](https://img.shields.io/maven-central/v/dev.bpm-crafters.process-engine-worker/process-engine-worker-spring-boot-starter)](https://central.sonatype.com/artifact/dev.bpm-crafters.process-engine-worker/process-engine-worker-spring-boot-starter)\n\n\n## Purpose of the library\n\nA small opinionated annotated-based SpringBoot worker implementation for creation of \nexternal task workers using Process-Engine-API.\n\n## How to use \n\nAdd the following dependency to your project's class path:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003edev.bpm-crafters.process-engine-worker\u003c/groupId\u003e\n  \u003cartifactId\u003eprocess-engine-worker-spring-boot-starter\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\nThe simplest way to implement the worker is to provide a component, with a worker method receiving typed\nobjects and returning a map of variables, which are automatically published as process variables.\n\n```java\n@Component\n@RequiredArgsConstructor\npublic class MySmartWorker {\n\n  private final FetchGoodsInPort fetchGoodsInPort;\n\n  @ProcessEngineWorker(\"fetchGoods\")\n  public Map\u003cString, Object\u003e fetchGoods(\n    @Variable(name = \"order\") Order order\n  ) {\n    // execute some business code\n    var fetched = fetchGoodsInPort.fetchGoods(order);\n    \n    return Map.of(\"shipped\", fetched);\n  }\n}\n\n```\n\nIf you need more control in your worker, you can supply more parameters in your worker method, including the\n`ExternalTaskCompletionApi` and invoke it manually:\n\n```java \n\n@Component\n@RequiredArgsConstructor\npublic class MyWorker {\n  \n  private final FetchGoodsInPort fetchGoodsInPort;\n  \n  @ProcessEngineWorker(topic = \"fetchGoods\", autoComplete = false)\n  public void fetchGoods(\n    TaskInformation taskInformation,\n    ExternalTaskCompletionApi externalTaskCompletionApi,\n    VariableConverter variableConverter,\n    Map\u003cString, Object\u003e processPayload\n  ) {\n    var order = variableConverter.mapToType(payload.get(\"order\"), Order.class);\n\n    // execute some business code\n    var fetched = fetchGoodsInPort.fetchGoods(order);\n\n    // complete the task using process engine API\n    externalTaskCompletionApi.completeTask(\n      new CompleteTaskCmd(taskInformation.getTaskId(), () -\u003e Map.of(\"shipped\", fetched))\n    ).get();\n  }\n}\n```\n\nParameter resolution of the method annotated with `ProcessEngineWorker` is based on a set of strategies\nregistered by the `ParameterResolver` bean. Currently, the following parameters are resolved:\n\n| Type                                     | Purpose                                                                   |\n|------------------------------------------|---------------------------------------------------------------------------|\n| TaskInformation                          | Helper abstracting all information about the external task.               |\n| ExternTaskCompletionApi                  | API for completing the external task manually                             |\n| VariableConverter                        | Special utility to read the process variable map and deliver typed value  | \n| Map\u003cString, Object\u003e                      | Payload object containing all variables.                                  |\n| Type annotated with `@Variable(\"name\")`  | Marker for a process variable.                                            |\n\nUsually, the requested variable is mandatory and the parameter resolver reports an error, if the requested variable is not \navailable in the process payload. If you want to inject the variable only if it exists in the payload you have two options.\nEither you set the parameter `@Variable(name = \"...\", mandatory = false)` or you use `Optional\u003cT\u003e` instead of `T` as a variable\ntype. If you are using Kotlin and don't like `Optional`, make sure to declare variable type as nullable (`T?` instead of `T`) and \nset the mandatory flag to `false`. \n\nIf the return type of the method is of type `Map\u003cString, Object\u003e` or compatible and the `autoComplete` flag is turned\non the annotation is `true` (defaults to `true`), the library will try to automatically complete the External Task \nusing the returned map as completion variables. If `autoComplete` is `true`, but no return value is provided, the task\nwill be completed without empty payload. This functionality is provided by the `ResultResolver` based on registered strategies.\n\nIf you want to throw a BPMN error, please throw an instance of a `BPMNErrorOccured`.\n\n## Customizations\n\nYou might want to register your own parameter resolution strategies. For this purpose, please construct \nthe parameter resolver bean on your own and register your own strategies. Your custom strategy must implement\n`ParameterResolutionStrategy` interface:\n\n```kotlin\n\n@Configuration\nclass MyConfig {\n\n  @Bean\n  fun myParameterResolver(): ParameterResolver {\n    return ParameterResolver.builder().addStrategy(\n      MyCustomParameterResolutionStrategy(),\n    ).build()\n  }\n}\n\n```\n\nOptionally, you might want to register own result resolution strategies. For this purpose, please construct\nthe result resolver bean on your own and register your own strategies:\n\n```kotlin\n\n@Configuration\nclass MyConfig {\n\n  @Bean\n  fun myResultResolver(): ResultResolver {\n    return ResultResolver.builder().addStrategy(\n      ResultResolutionStrategy(\n        resultMatcher = { method -\u003e ... },\n        resultConverter = { result -\u003e ... },\n      ),\n    ).build()\n  }\n}\n\n```\n\nIf you want to switch the entire library off (for example you are in the context of an integration test, and parts of your Process Engine API are deactivated),\nyou can do it by setting the property `dev.bpm-crafters.process-api.worker.enabled` to `false`.\n\n## Examples\n\nThere is an `Order fulfillment` example, you can easily try out. It follows the approach of \nclean architecture and uses Process Engine API and Process Engine Worker libraries. \nTo run it, you have several options:\n\n### Running locally using Camunda 7 embedded\n\n1. Start `FulfillmentProcessApplication` activating profile `c7embedded` Spring profile.\n\n### Running locally using self-managed Camunda 8\n\n1. Start `docker-compose.yaml` (this will start containerized Zeebe locally)\n2. Start `FulfillmentProcessApplication` activating Spring profile `c8sm`.\n\n### Running using Camunda SaaS\n\n1. Start `FulfillmentProcessApplication` activating Spring profile `c8cloud` and pass the following environment variables:\n\n```properties\nZEEBE_REGION=..\nZEEBE_CLUSTER_ID=..\nZEEBE_CLIENT_ID=..\nZEEBE_CLIENT_SECRET=...\n```\n\nAfter starting application, you can either use Open API endpoints or just run the\nHTTP client tests using your IntelliJ, located in the example directory.\n\nDon't forget to first deploy the process! \nEither manually via operate / modeler, or with the HTTP client script: \nc8-deploy-process.http\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpm-crafters%2Fprocess-engine-worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpm-crafters%2Fprocess-engine-worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpm-crafters%2Fprocess-engine-worker/lists"}