{"id":16514358,"url":"https://github.com/openwms/org.openwms.tms.routing","last_synced_at":"2026-06-22T02:32:02.548Z","repository":{"id":45184710,"uuid":"72306464","full_name":"openwms/org.openwms.tms.routing","owner":"openwms","description":"OpenWMS TMS Routing Service for Material Flow Control (MFC)","archived":false,"fork":false,"pushed_at":"2024-04-16T13:44:52.000Z","size":11794,"stargazers_count":1,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-02T01:11:19.799Z","etag":null,"topics":["camunda","flowable","microservices","openwms","spring-boot","spring-cloud","workflow"],"latest_commit_sha":null,"homepage":"https://openwms.github.io/org.openwms.tms.routing","language":"Java","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/openwms.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}},"created_at":"2016-10-29T20:00:01.000Z","updated_at":"2023-11-29T05:01:27.000Z","dependencies_parsed_at":"2023-10-03T00:49:28.896Z","dependency_job_id":"5a1a3601-cb86-48e9-9d30-771882c94ccf","html_url":"https://github.com/openwms/org.openwms.tms.routing","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwms%2Forg.openwms.tms.routing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwms%2Forg.openwms.tms.routing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwms%2Forg.openwms.tms.routing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwms%2Forg.openwms.tms.routing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openwms","download_url":"https://codeload.github.com/openwms/org.openwms.tms.routing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219860117,"owners_count":16556027,"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":["camunda","flowable","microservices","openwms","spring-boot","spring-cloud","workflow"],"created_at":"2024-10-11T16:12:21.111Z","updated_at":"2026-06-22T02:32:02.517Z","avatar_url":"https://github.com/openwms.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Purpose\nThe TMS Routing service is used in automatic warehouses to route `TransportUnits` on conveyors through the warehouse. It is responsible to\nhandle incoming messages and selects the appropriate workflow process that finally executes the handling. The workflow is a BPMN 2.0\ncompliant workflow, with extensions of the used workflow engine.\n\n# Resources\nDocumentation at [Wiki](https://wiki.openwms.cloud/projects/tms-routing-service/wiki)\n\n[![Build status](https://github.com/openwms/org.openwms.tms.routing/actions/workflows/master-build.yml/badge.svg)](https://github.com/openwms/org.openwms.tms.routing/actions/workflows/master-build.yml)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n[![Docker pulls](https://img.shields.io/docker/pulls/openwms/org.openwms.tms.routing)](https://hub.docker.com/r/openwms/org.openwms.tms.routing)\n[![Join the chat at https://gitter.im/openwms/org.openwms](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/openwms/org.openwms?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n# Details\nA typical and simple workflow to handle incoming OSIP REQ_ messages could look like this:\n\n![Workflow][1]\n \n(1) Whenever a REQ_ message arrives, the `TransportUnit` with the given `Barcode` is booked onto the `Location` provided in the message.\n\n(2) For the current `TransportUnit` a `TransportOrder` is created with the target `LocationGroup` equals to `FGSTOCK`.\n\n(3) In the final step the system triggers a service to send an OSIP RES_ message to the underlying subsystem (i.e. PLC or Raspberry Pi) with\nthe next `Location` coordinate to move the `TransportUnit` to.\n\nThe shown BPMN snippet looks in XML like this:\n\n```\n    \u003cserviceTask id=\"Task1\" name=\"Book to current Location\" activiti:expression=\"#{transportUnitApi.moveTU(in.msg.barcode, in.msg.actualLocationId)}\" /\u003e\n    \u003cserviceTask id=\"Task2\" name=\"Create TransportOrder to Stock\" activiti:expression=\"#{transportOrderApi.createTO(\u0026quot;FGSTOCK\u0026quot;)}\"\u003e\u003c/serviceTask\u003e\n    \u003cserviceTask id=\"Task3\" name=\"Send OSIP RES telegram\" activiti:expression=\"#{responder.sendTo(in.msg.flexField1)}\"\u003e\u003c/serviceTask\u003e\n```\n\nNotice that the flow and the expressions are modeled in [Flowable](https://www.flowable.org) Model Explorer and there are extensions to the\nBPMN standard. Other supported workflow engines like Camunda or Activiti have their own XML namespace extensions, but the XML element names\nare almost the same.\n\n## Benefits\nWhy did we choose BPMN for the transport management system? From the experience we have from projects and systems in the past we know that\nthe physical layout of a system and the material flow is something that always needs to be adopted to the particular customer project.\nChanging the material flow must happen rapidly without any compilation nor deployment interruption.\n\nThe second huge benefit of using BPMN for the material flow handling is the advantage of having the same notation for business people as\nwell as software engineers, so both can define and communicate on the same process models.\n\nUsually after doing a couple of projects an engineer or the project team has a library of well known business functions that they can use to\nbuild new flows for new customer projects. Not only the microservice functions can be reused across projects but also BPMN flows. We misuse\nthe concept of BPMN for a good purpose :-)\n\n## Features\nThe current implementation allows to refer standard Spring managed beans within BPMN workflows. Remotely http accessible microservices can\nbe accessed with support of `Feign`. Therefor the TMS Routing service needs to have the Feign client interface definitions on the classpath\nat startup, by simple extending the classpath with the JAR file when the process is started.\n\n### Static Routing\nRequests from a PLC for a next target can be answered statically by using a routing table. For this reason a `Route` may have `RouteDetails`\nentries in a defined order (ordered by the `pos` attribute). The actual location from the telegram is used to determine the next target. In\nthe selected workflow a call to `#{routing.sendToNextLocation()}` chooses the next routing location.\n\n### Hard Coded Routing\nThe workflow that calls the microservice to send the request telegram could pass the next `Location` hard-coded within the workflow. This is\nmore or less the simplest solution but has the drawback that the workflow may not be reused, because the target is hard-coded.\n \n### Dynamic Routing\nDynamic routing is another strategy in contrast to static or hard-coded routing. The workflow can be customized with so-called\n*Flex Attributes*. This means a workflow can be called with parameters and these parameters come from a defined `Action`. The `Action` might\nbe specific to the project. BPMN workflows should be reusable across projects - `Actions` may not.\n\n# Configuration\nThe following Spring profiles are currently supported:\n`ASYNCHRONOUS` - Run with AMQP communication\n`CAMUNDA` - Enable Camunda as workflow engine\n`DISTRIBUTED` - Enables the service to run in a microservice system\n`FLOWABLE` - Use Flowable as workflow engine (default)\n\n# Development\n\n## Build\nTo build an executable JAR file that can run either in a standalone or in a distributed environment call:\n\n```\n$ mvn package\n```\n\n## Run\nAfter the deliverable has been built it can be started with:\n```\n$ java -jar target/openwms-tms-routing-exec.jar\n```\n\nIn case the service has been started in a distributed environment along a central configuration server and service registry the\n`DISTRIBUTED` profile needs to be activated. For processing over AMQP also the `ASYNCHRONOUS` profile must be active:\n\n```\n$ java -jar target/openwms-tms-routing-exec.jar --spring.profiles.active=DISTRIBUTED,ASYNCHRONOUS\n```\n\nThe service is also available as Docker image on Docker Hub and can be started with:\n```\n$ docker run -it openwms/org.openwms.tms.routing:latest\n```\n \n# Appendix\n\n## Further reading\n\n| ID   | Description                                                                                                               |\n|------|---------------------------------------------------------------------------------------------------------------------------|\n| L001 | [Secured Eureka First Microservices](https://github.com/openwms/org.openwms/wiki/Secured-Eureka-First-services-on-Heroku) |\n| L002 | [Development Process](src/site/markdown/development.md) |\n\n[1]: src/site/resources/images/workflow.png\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenwms%2Forg.openwms.tms.routing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenwms%2Forg.openwms.tms.routing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenwms%2Forg.openwms.tms.routing/lists"}