{"id":37020660,"url":"https://github.com/technologicgroup/cluster-boost","last_synced_at":"2026-01-14T02:24:47.871Z","repository":{"id":57727488,"uuid":"263944462","full_name":"technologicgroup/cluster-boost","owner":"technologicgroup","description":"Spring friendly cluster library for Ignite","archived":false,"fork":false,"pushed_at":"2021-12-24T08:56:28.000Z","size":210,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-07T17:56:24.944Z","etag":null,"topics":["cluster-boost","gridgain","ignite","spring-boot"],"latest_commit_sha":null,"homepage":"https://technologicgroup.com","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/technologicgroup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":"FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"Nurkambay"}},"created_at":"2020-05-14T14:54:28.000Z","updated_at":"2025-02-08T10:14:58.000Z","dependencies_parsed_at":"2022-09-26T21:51:49.975Z","dependency_job_id":null,"html_url":"https://github.com/technologicgroup/cluster-boost","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/technologicgroup/cluster-boost","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technologicgroup%2Fcluster-boost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technologicgroup%2Fcluster-boost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technologicgroup%2Fcluster-boost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technologicgroup%2Fcluster-boost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/technologicgroup","download_url":"https://codeload.github.com/technologicgroup/cluster-boost/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technologicgroup%2Fcluster-boost/sbom","scorecard":{"id":872136,"data":{"date":"2025-08-11","repo":{"name":"github.com/technologicgroup/cluster-boost","commit":"3cbf617707387c8f8dd8b9d104da4d32e9d0f3d7"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"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":"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["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":"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":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/technologicgroup/cluster-boost/maven.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/technologicgroup/cluster-boost/maven.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned 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":"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":"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":"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":"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 'master'"],"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":"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-24T04:36:33.952Z","repository_id":57727488,"created_at":"2025-08-24T04:36:33.952Z","updated_at":"2025-08-24T04:36:33.952Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["cluster-boost","gridgain","ignite","spring-boot"],"created_at":"2026-01-14T02:24:47.180Z","updated_at":"2026-01-14T02:24:47.863Z","avatar_url":"https://github.com/technologicgroup.png","language":"Java","funding_links":["https://github.com/sponsors/Nurkambay"],"categories":[],"sub_categories":[],"readme":"# Spring friendly cluster library for Ignite\n\n## Version 1.1\n\n## Description\nFull Spring-integrated solution for Ignite cluster that helps to implement your first flexible Ignite cluster easily.\n\n## Release 1.1 notes \n1. Fix for `Chain.reduce` functionality\n1. Change bean providers behavior. If bean provider can't inject a bean, `RuntimeException` will be thrown. \n\n## Main features\n\n1. [Cluster ready event](#1-cluster-ready-event)\n1. [Self-registered repositories](#2-self-registered-repositories)\n1. [Run Spring beans as a cluster tasks](#3-run-spring-beans-as-a-cluster-tasks)\n1. [Chain running](#4-chain-running)\n1. [Audit](#5-audit)\n\n## Maven dependency\n\n### Common library\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.technologicgroup.cluster\u003c/groupId\u003e\n    \u003cartifactId\u003ecluster-boost-ignite\u003c/artifactId\u003e\n    \u003cversion\u003e1.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Library with audit support\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.technologicgroup.cluster\u003c/groupId\u003e\n    \u003cartifactId\u003ecluster-boost-ignite-audit\u003c/artifactId\u003e\n    \u003cversion\u003e1.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Examples\n\n### [Examples repository](https://github.com/technologicgroup/cluster-boost-examples)\n\n1. [example-01](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-01) - cluster ready event, self-registered repositories \n\n1. [example-02](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-02) - run Spring bean as a cluster task  \n\n1. [example-03](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-03) - chain running   \n\n1. [example-04](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-04) - chain running with audit\n\n\n## 1. Cluster ready event\n\nIgnite cluster have set of nodes hosted on different hosts.\n\nNodes are entering cluster not at the same time but Ignite \nallows you to use cluster even when not all nodes in the cluster \nexists, and some of them maybe failed to start.\n\nIn this situation when you want to use cluster only if all \nnodes successfully started you should listen to **ClusterReadyEvent**\n\nWhen all nodes entered the cluster and cluster is ready for tasks, \n**ClusterReadyEvent** fires on every node of the cluster.\n\n```java\n@Slf4j\n@Service\n@RequiredArgsConstructor\npublic class ClusterReadyConsumer implements ApplicationListener\u003cClusterReadyEvent\u003e {\n  private final Cluster cluster;\n\n  @Override\n  public void onApplicationEvent(@NotNull ClusterReadyEvent event) {\n    log.info(\"Cluster is ready: {}\", event);\n  }\n}\n```\n\nYou need to specify all expected nodes in the **application.properties** file.\n\nIn the following example cluster will expect 2 nodes from localhost:\n\n```\ncluster.hosts=localhost:47500..47509,localhost:47500..47509\n```\n\nYou can also specify a timeout in mills for the cluster activation. \n\nIf at least one node will not enter the cluster timeout Exception will be thrown.\n\n```\ncluster.startupTimeout=20000\n```\n\nBy default timeout is 60000 mills.\n\n## 2. Self-registered repositories\n\nTo define a memory cache you need to define just one repository class\n\n```java\n@Repository\npublic class TestRepository extends CommonRepository\u003cTestKey, TestValue\u003e {\n\n}\n```\n\nThis repository class provides **local read** and **cluster write** functionality for data class.\nLocal read and cluster read operations were divided into 2 classes to avoid unexpected slow read operations.\n\nLocal read operations are very fast because the data is stored on the current node and no network calls are needed. \n\nTo have full access to cluster data as **cluster read/write** you need to define \na data accessor service based on the repository:\n\n```java\n@Service\npublic class TestAccessor extends CommonDataAccessor\u003cTestKey, TestValue\u003e {\n  public TestAccessor(CommonRepository\u003cTestKey, TestValue\u003e repository) {\n    super(repository);\n  }\n}\n```\n\n**Working application example: [example-01](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-01)** \n\n## 3. Run Spring beans as a cluster task\n\nYou do not need to define some special classes for a cluster tasks anymore.\nIf you want to run some code on every cluster node with a parameter you just need to define one Spring bean class\n\n```java\n@Service\n@AllArgsConstructor\npublic class TaskBean implements ClusterTask\u003cInteger, Boolean\u003e {\n  @Override\n  public Boolean run(Integer arg) {\n    return arg \u003e 0;\n  }\n}\n```\n\nand run it:\n\n```java\nCollection\u003cBoolean\u003e results = cluster.runBean(TaskBean.class, 5);\n```\n\nThe code defined in the **run** method of the bean will be executed on every \nnode, and you can feel like it is a local operation for you.\n\nResult from every node will be collected to the collection of results.\n\nIn the task bean you can easily autowire any Spring bean you want \n(f.e. a repository to access local data) without any troubles. \n\n**Working application example: [example-02](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-02)** \n\n## 4. Chain running\n\nWhen you are using classic Ignite and do not want to overlap 2 tasks\nyou need to run a task for a cluster and wait until this \ntask will be finished on every cluster node and after that run another task. \n\nBut what if some nodes performs faster that others?\nHow to run task 2 on the *fast* node and wait for finishing on other nodes? \n\nHere we go, chain running:\n\n```java\nboolean chainResult = Chain.of(cluster)                         // Line 1\n  .map(RunnableBean.class, \"Chain argument\")                    // Line 2\n  .map(TaskBean.class)                                          // Line 3\n  .filter(r -\u003e r.getNodeId().equals(cluster.getLocalNode()))    // Line 4  \n  .collect(c -\u003e c.stream().allMatch(Boolean::booleanValue));    // Line 5\n```\n\n### Line 1 - define a chain on a cluster\n\nYou can also define a cluster group to run a chain\n\n### Line 2 - add a new chain step \n\nThe **RunnableBean** operation will be performed on every node, and\nthe result of this step will be passed as an argument to the next chain step for every node\n\n### Line 3 - add a new chain step\n \nResult of the previous step chain will pass as an argument to the **TaskBean**.\n\nFor now no operations on the cluster actually are not running yet but if you say to the chain **run**: \n\n1. **RunnableBean** will be executed on every node and when a node will finish the task the result will be passed to **TaskBean** task and \n\n2. **TaskBean** will be executed on this node even if other nodes are still in progress with **RunnableBean**.\n\n### Line 4 - filter operation for a chain\nHere we run chain bean tasks (**RunnableBean** -\u003e **TaskBean**) on every node and waiting results.\nAfter results are available defined predicate will be applied to filter them.\n\nNext chain step will be performed only for nodes that were passed a filter. And in the next bean task will be passed a result \nof previuos step from Line 3 (**TaskBean** result).\n\n### Line 5 - collect results  \n\n**Working application example: [example-03](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-03)** \n\n## 5. Audit\n\nTo track running beans on cluster substitute common library with audit version\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.technologicgroup.cluster\u003c/groupId\u003e\n    \u003cartifactId\u003ecluster-boost-ignite-audit\u003c/artifactId\u003e\n    \u003cversion\u003e1.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThis will provide access to tracking data VIA **AuditService** that you can inject to any Spring bean:  \n\n```java\nprivate final AuditService auditService;\n```\n\nAll running beans will be tracked by default with random UUID, but you can specify it by implementing Trackable interface for bean arguments:\n\n```java\n@Data\n@AllArgsConstructor\npublic class TestData implements Trackable {\n  private String trackingId;\n  private String id;\n  private int foo;\n}\n```\n\nAll tracked data will be stored in the automatically created Ignite cache and will be accessible with **AuditService** by trackingId\nYou can use one **trackingId** for multiple operations on the cluster or for a chain running:\n\n```java\nCollection\u003cChainResult\u003cString\u003e\u003e results = Chain.of(cluster)\n  .track(trackingId)                             // Track all chain steps with trackingId\n  .map(ChainBean1.class, \"Chain argument\")       // Start chain with string argument\n  .filter(r -\u003e r.getResult() == 1)               // Continue chain only for odd nodes\n  .map(ChainBean2.class)                         // On even nodes create a string result\n  .run();                                        // Run chain steps\n\n```  \n\n**Working application example: [example-04](https://github.com/technologicgroup/cluster-boost-examples/tree/master/example-04)** \n  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnologicgroup%2Fcluster-boost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnologicgroup%2Fcluster-boost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnologicgroup%2Fcluster-boost/lists"}