{"id":19307464,"url":"https://github.com/fair-acc/opencmw-java","last_synced_at":"2026-03-13T20:36:35.634Z","repository":{"id":37828864,"uuid":"330682200","full_name":"fair-acc/opencmw-java","owner":"fair-acc","description":"Open Common Middle-Ware library for accelerator equipment- and beam-based control systems at FAIR.","archived":false,"fork":false,"pushed_at":"2026-01-26T16:35:57.000Z","size":2960,"stargazers_count":9,"open_issues_count":16,"forks_count":4,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-01-27T03:29:00.699Z","etag":null,"topics":["cross-platform","java","microservice","middleware","modular","opencmw","rest-api","serialisation","serialization","zeromq"],"latest_commit_sha":null,"homepage":"https://opencmw.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fair-acc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2021-01-18T13:55:20.000Z","updated_at":"2026-01-16T17:39:36.000Z","dependencies_parsed_at":"2024-11-10T00:11:20.417Z","dependency_job_id":"cae833ae-5e60-44fc-9807-22c6ff8e921b","html_url":"https://github.com/fair-acc/opencmw-java","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/fair-acc/opencmw-java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fair-acc%2Fopencmw-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fair-acc%2Fopencmw-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fair-acc%2Fopencmw-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fair-acc%2Fopencmw-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fair-acc","download_url":"https://codeload.github.com/fair-acc/opencmw-java/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fair-acc%2Fopencmw-java/sbom","scorecard":{"id":391495,"data":{"date":"2025-08-11","repo":{"name":"github.com/fair-acc/opencmw-java","commit":"dcab0027bfd4e2af7d52d5d4ebb00221d5905a7f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"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":"Code-Review","score":4,"reason":"Found 8/18 approved changesets -- score normalized to 4","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":"Dangerous-Workflow","score":0,"reason":"dangerous workflow patterns detected","details":["Warn: untrusted code checkout '${{ github.event.workflow_run.head_branch }}': .github/workflows/coverity.yml:21"],"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:16","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:17","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Warn: no topLevel permission defined: .github/workflows/coverity.yml:1","Warn: no topLevel permission defined: .github/workflows/dispatch_coverity.yml:1","Warn: no topLevel permission defined: .github/workflows/maven.yml:1","Info: no jobLevel write permissions found"],"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":"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":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"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":"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":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: not a valid arithmetic operator: diff: config/hooks/pre-commit:0","Info: Possibly incomplete results: error parsing shell code: not a valid arithmetic operator: status: formatFiles.sh:0","Info: Possibly incomplete results: error parsing shell code: not a valid arithmetic operator: diff: formatLastCommit.sh:0","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coverity.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/coverity.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coverity.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/coverity.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coverity.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/coverity.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coverity.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/coverity.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/maven.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/maven.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:95: update your workflow using https://app.stepsecurity.io/secureworkflow/fair-acc/opencmw-java/maven.yml/main?enable=pin","Info:   0 out of  15 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"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":"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: GNU Lesser General Public License v3.0: 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":"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":"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 23 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-18T17:55:43.077Z","repository_id":37828864,"created_at":"2025-08-18T17:55:43.077Z","updated_at":"2025-08-18T17:55:43.077Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30474934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T17:15:31.527Z","status":"ssl_error","status_checked_at":"2026-03-13T17:15:22.394Z","response_time":60,"last_error":"SSL_read: 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":["cross-platform","java","microservice","middleware","modular","opencmw","rest-api","serialisation","serialization","zeromq"],"created_at":"2024-11-10T00:11:08.382Z","updated_at":"2026-03-13T20:36:35.605Z","avatar_url":"https://github.com/fair-acc.png","language":"Java","readme":"\u003cpicture\u003e\n\u003csource srcset=\"assets/OpenCMW_logo_w.svg\" media=\"(prefers-color-scheme: dark)\"\u003e\n\u003c!--suppress HtmlDeprecatedAttribute --\u003e\n\u003cimg align=\"right\" src=\"assets/OpenCMW_logo_b_bg.svg\" alt=\"OpenCMW Logo\" height=\"75\"\u003e\n\u003c/picture\u003e\n\n[![Gitter](https://badges.gitter.im/fair-acc/opencmw.svg)](https://gitter.im/fair-acc/opencmw?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n[![License](https://img.shields.io/badge/License-LGPL%203.0-blue.svg)](https://opensource.org/licenses/LGPL-3.0)\n[![Maven Central](https://img.shields.io/maven-central/v/io.opencmw/opencmw)](https://search.maven.org/search?q=g:io.opencmw)\n\n[![Language grade: Java](https://img.shields.io/lgtm/grade/java/github/fair-acc/opencmw-java)](https://lgtm.com/projects/g/fair-acc/opencmw-java/context:java)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9c7215713a8d4e71a751ae70ec31f2db?branch=main)](https://app.codacy.com/gh/fair-acc/opencmw-java)\n[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/9c7215713a8d4e71a751ae70ec31f2db)](https://www.codacy.com/gh/fair-acc/opencmw-java/dashboard?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=fair-acc/opencmw-java\u0026utm_campaign=Badge_Coverage)\n[![Coverity Build Status](https://scan.coverity.com/projects/fair-acc-opencmw-java/badge.svg)](https://scan.coverity.com/projects/fair-acc-opencmw-java)\n# Open Common Middle-Ware\n... is a modular event-driven [micro-](https://en.wikipedia.org/wiki/Microservices) and [middle-ware](https://en.wikipedia.org/wiki/Middleware#:~:text=Middleware%20is%20a%20computer%20software,described%20as%20%22software%20glue%22.)\nlibrary for equipment- and beam-based monitoring as well as feedback control systems for the [FAIR](https://fair-center.eu/) Accelerator Facility ([video](https://www.youtube.com/watch?v=gCHzDR7hdoM)) \nor any other project that may find this useful.\n\nIn a nut-shell: it provides common communication protocols, interfaces to numerical data [visualisation](https://github.com/GSI-CS-CO/chart-fx)\nand processing tools that shall aid accelerator engineers and physicist to write functional high-level monitoring and\n(semi-)automated feedback applications that interact, simplify and improve our accelerator operation or its individual sub-systems.\nMost notably, the focus is put on minimising the amount of boiler-plate code, programming expertise, and to significantly\nlower the entry-threshold that is required to perform simple to advanced monitoring or 'measure-and-correct' applications\nwhere the frame-work takes care of most of the communication, [data-serialisation](docs/IoSerialiser.md), data-aggregation\nand buffering, settings management, Role-Based-Access-Control (RBAC), and other boring but necessary control system integrations\nwhile still being open to expert-level modifications, extensions or improvements.\n\n### General Schematic\nOpenCMW combines [ZeroMQ](https://zeromq.org/)'s [Majordomo](https://rfc.zeromq.org/spec/7/) with LMAX's [disruptor](https://lmax-exchange.github.io/disruptor/) design pattern that both provide a very efficient lock-free mechanisms for distributing, streaming and processing of data objects. A schematic outline of the internal [architecture](https://edms.cern.ch/document/2444348/1) ([local copy](assets/F-CS-SIS-en-B_0006_FAIR_Service_Middle_Ware_V1_0.pdf)) is shown below:\n\n![OpenCMW architectural schematic](./assets/FAIR_microservice_schematic.svg)\n\n### Glossary\n\n*Majordomo Broker* or *'Broker':* is the central authority where multiple workers can register their services, allowing clients to perform get, set or subscriptions requests.\nThere can be multiple brokers for subset of services.\n\n*Worker:* functional unit which provides one or more services that are registered with a broker. OpenCMW provides base implementations at different abstraction levels ([BasicMdpWorker](server/src/main/java/io/opencmw/server/BasicMdpWorker.java) (low-level) and \n[MajordomoWorker](server/src/main/java/io/opencmw/server/MajordomoWorker.java)) as well as different internal and external service workers, e.g. MajordomoRestPlugin or the broker's mmi services. Workers communicate with the broker using the OpenCMW worker [protocol](docs/MajordomoProtocol.md) internally or externally via ZeroMQ sockets via `inproc`, `tcp`, `udp` or another suitable low-level network protocol scheme that is supported by ZeroMQ.\n\n*Endpoint:* address for a service following the standardised [URI](https://tools.ietf.org/html/rfc3986) convention of `scheme:[//authority]path[?query][#fragment]`. Services usually omit the authority part and provide only relative paths as this information is managed and added by their broker.\nEach broker acts individually as a DNS for its own services as well as can forward this information to another (for the time being) central DNS Broker.\n\n*internal/mmi workers:* each broker by default starts some lightweight management services as specified by the Majodomo [mmi](https://rfc.zeromq.org/spec/8/) extension:\n- `\u003coptional broker name\u003e/mmi.service`: endpoints of all services registered at this broker\n- `\u003coptional broker name\u003e/mmi.openapi`: openapi descriptions for the services\n- `\u003coptional broker name\u003e/mmi.dns`: service lookup\n\n*Context:* information that (if applicable) is matched to the URI's query parameter and required for every request and reply, specified by a domain object.\nThey (partially) map to the filters used in the EventStore and the query parameters of the communication library. The context is used for (partial/wildcard) matching and can be used in the EventStore's filter config.\n\n*EventStore:* based on LMAX's [disruptor](https://lmax-exchange.github.io/disruptor/) pattern, the EventStore provides datastructures and setup methods \nto define processing pipelines based on incoming data. (N.B. Java specific: a special worker allows reclaiming memory from expired events using a special\nSharedPointer implementation.)\n\n*EventHandler:* used to define specific internal processing steps based on EventStore events. The last EventHandler is usually also a Majordomo worker to export the processed information via the network.\n\n*Publisher:* the [DataSourcePublisher](./client/src/test/java/io/opencmw/client/DataSourceExample.java) provides an interface to populate the EventStore \nring-buffer with events from OpenCMW, REST services or other sources. \nWhile using disruptor ring-buffers is the preferred and most performing options, the client also supports classic patterns of registering call-back functions or returning `Future\u003creyly objects\u003e` objects.\n\n### Example\nThe following provides some flavour of how a simple service can be implemented using OpenCMW with only a few lines of\ncustom user-code ([full sample](https://github.com/fair-acc/opencmw-java/tree/createReadme/server-rest/src/test/java/io/opencmw/server/rest/samples/BasicSample.java)):\n\n```Java\n@MetaInfo(description = \"My first 'Hello World!' Service\")\npublic static class HelloWorldWorker extends MajordomoWorker\u003cBasicRequestCtx, NoData, ReplyData\u003e {\n    public HelloWorldWorker(final ZContext ctx, final String serviceName, final RbacRole\u003c?\u003e... rbacRoles) {\n        super(ctx, serviceName, BasicRequestCtx.class, NoData.class, ReplyData.class, rbacRoles);\n\n        // the custom used code:\n        this.setHandler((rawCtx, requestContext, requestData, replyContext, replyData) -\u003e {\n            final String name = Objects.requireNonNullElse(requestContext.name, \"\");\n            LOGGER.atInfo().addArgument(rawCtx.req.command).addArgument(rawCtx.req.topic)\n                    .log(\"{} request for worker - requested topic '{}'\");\n            replyData.returnValue = name.isBlank() ? \"Hello World\" : \"Hello, \" + name + \"!\";\n            replyContext.name = name.isBlank() ? \"At\" : (name + \", at\") + \" your service!\";\n        });\n\n        // simple asynchronous notify example - (real-world use-cases would use another updater than Timer)\n        new Timer(true).scheduleAtFixedRate(new TimerTask() {\n            private final BasicRequestCtx notifyContext = new BasicRequestCtx(); // re-use to avoid gc\n            private final ReplyData notifyData = new ReplyData(); // re-use to avoid gc\n            private int i;\n            @Override\n            public void run() {\n                notifyContext.name = \"update context #\" + i;\n                notifyData.returnValue = \"arbitrary data - update iteration #\" + i++;\n                try {\n                    HelloWorldWorker.this.notify(notifyContext, notifyData);\n                } catch (Exception e) {\n                    LOGGER.atError().setCause(e).log(\"could not notify update\");\n                    // further handle exception if necessary\n                }\n            }\n        }, TimeUnit.SECONDS.toMillis(1), TimeUnit.SECONDS.toMillis(2));\n    }\n}\n\n@MetaInfo(description = \"arbitrary request domain context object\", direction = \"IN\")\npublic static class BasicRequestCtx {\n    @MetaInfo(description = \" optional 'name' OpenAPI documentation\")\n    public String name;\n}\n\n@MetaInfo(description = \"arbitrary reply domain object\", direction = \"OUT\")\npublic static class ReplyData {\n    @MetaInfo(description = \" optional 'returnValue' OpenAPI documentation\", unit = \"a string\")\n    public String returnValue;\n}\n```\n\nThese services can be accessed using OpenCMW's own [DataSourcePublisher](./client/src/test/java/io/opencmw/client/DataSourceExample.java)\nclient that queries or subscribes using one of the highly-optimised binary, JSON or other wire-formats and [ZeroMQ](https://zeromq.org/)-\nor RESTful (HTTP)-based high-level protocols, or through a simple RESTful web-interface that also provides simple\n'get', 'set' and 'subscribe' functionalities while developing, for testing, or debugging:\n\n![web/REST interface example](docs/BasicExampleSnapshot.png)\n\nThe basic HTML rendering is based on Apache's [velocity](https://velocity.apache.org/) template engine and can be customised.\nAlternatively, the [ClipboardWorker](/server/src/main/java/io/opencmw/server/ClipboardWorker.java) can be used\nin combination with other UI technologies (e.g. [chartfx](https://github.com/GSI-CS-CO/chart-fx)) to create\nmore complex monitoring or fixed-displays with only a few hundred lines of code. For more efficient, complex and cross-platform\nUI designs it is planned to allow embedding of WebAssembly-based ([WASM](https://en.wikipedia.org/wiki/WebAssembly)) applications.\n\n### Performance\nThe end-to-end transmission achieving roughly 10k messages per second for synchronous communications and\nabout 140k messages per second for asynchronous and or publish-subscribe style data acquisition (TCP link via locahost)\nwith the domain-object abstraction and serialiser taking typically only 5% of the overall performance w.r.t. bare-metal\ntransmissions (i.e. raw byte buffer transmission performance via ZeroMQ):\n```\nCPU:AMD Ryzen 9 5900X 12-Core Processor\ndescription; n_exec; n_workers #0; #1; #2; #3; #4; avg\nget,  sync, future,     domain-object ; 10000; 1;   7124.48;  10166.67;  10651.01;  10846.83;  10968.31;  10658.21\nget,  sync, eventStore, domain-object ; 10000; 1;   9842.93;   9789.00;   9777.39;   9270.77;   9805.15;   9660.58\nget,  sync, eventStore, raw-byte[]    ; 10000; 1;  12237.14;  12256.34;  12259.75;  13151.36;  13171.80;  12709.81\nget, async, eventStore, domain-object ; 10000; 1;  46134.05;  50850.82;  48108.52;  54487.72;  46171.67;  49904.68\nget, async, eventStore, raw-byte[]    ; 10000; 1;  48972.78;  53278.84;  52600.98;  54832.65;  53027.51;  53435.00\nsub, async, eventStore, domain-object ; 10000; 1;  70222.57; 115074.45; 161601.24; 132852.50; 164151.85; 143420.01\nsub, async, eventStore, raw-byte[]    ; 10000; 1; 121308.73; 123829.95; 124283.37; 166348.23; 128094.40; 135638.99\nsub, async, callback,   domain-object ; 10000; 1; 111274.04; 118184.64; 123098.70; 116418.52; 107858.25; 116390.03\n```\nYour mileage may vary depending on the specific domain-object, processing logic, and choice of hardware (CPU/RAM),\nbut you can check and compare the results for your platform using the [RoundTripAndNotifyEvaluation](./concepts/src/test/java/io/opencmw/concepts/RoundTripAndNotifyEvaluation.java)\nand/or [MdpImplementationBenchmark](./client/src/test/java/io/opencmw/client/benchmark/MdpImplementationBenchmark.java) benchmarks.\nWhile -- of course -- always subject to improvements, this initial not yet optimised performance is acceptable for our\ninitial purposes of interfacing with Java-based (often RMI-only) systems.\n\n### Documentation\n.... more to follow.\n\n### Don't like Java?\nFor faster applications and interaction hardware-based systems (e.g. DAQ controller/digitizer, etc.), a C++-based\n[OpenCMW](https://github.com/fair-acc/opencmw-cpp) twin-project is being developed which follows the same functional style\nbut takes advantage of more concise implementation and C++-based type safety.\nStay tuned...\n\n### Acknowledgements\nThe implementation heavily relies upon and re-uses time-tried and well-established concepts from [ZeroMQ](https://zeromq.org/)\n(notably the [Majordomo](https://rfc.zeromq.org/spec/7/) communication pattern, see [Z-Guide](https://zguide.zeromq.org/docs/chapter4/#Service-Oriented-Reliable-Queuing-Majordomo-Pattern)\nfor details), LMAX's lock-free ring-buffer [disruptor](https://lmax-exchange.github.io/disruptor/), [GNU-Radio](https://www.gnuradio.org/)\nreal-time signal processing framework, [Javalin] for the RESTful interface, as well as previous implementations and\nexperiences gained at [GSI](https://www.gsi.de/), [FAIR](https://fair-center.eu/) and [CERN](https://home.cern/).\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffair-acc%2Fopencmw-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffair-acc%2Fopencmw-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffair-acc%2Fopencmw-java/lists"}