diff --git a/.github/workflows/pcgcli-main.yml b/.github/workflows/pcgcli-main.yml
deleted file mode 100644
index 003b2e5..0000000
--- a/.github/workflows/pcgcli-main.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-name: Partitioned Consumer Groups CLI Main Snapshot
-
-on:
- push:
- branches:
- - main
- paths:
- - 'pcgroups-cli/**'
-
-jobs:
- build:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./pcgroups-cli
- steps:
- - name: Set up JDK
- uses: actions/setup-java@v5
- with:
- java-version: '21'
- distribution: 'temurin'
- - name: Check out code
- uses: actions/checkout@v4
- - name: Build with Gradle
- run: |
- chmod +x gradlew && ./gradlew clean test uberJar
- - name: Build with Maven
- run: mvn clean package
- - name: Validate Gradle Uber was created
- run: |
- FILE_PATH="build/libs/cg.jar"
- if [ -f "$FILE_PATH" ]; then
- echo "Validation successful: $FILE_PATH was created."
- else
- echo "Validation failed: $FILE_PATH was not found."
- exit 1 # Fails the workflow step
- fi
- - name: Validate Maven Uber was created
- run: |
- FILE_PATH="target/cg.jar"
- if [ -f "$FILE_PATH" ]; then
- echo "Validation successful: $FILE_PATH was created."
- else
- echo "Validation failed: $FILE_PATH was not found."
- exit 1 # Fails the workflow step
- fi
diff --git a/.github/workflows/pcgcli-pr.yml b/.github/workflows/pcgcli.yml
similarity index 57%
rename from .github/workflows/pcgcli-pr.yml
rename to .github/workflows/pcgcli.yml
index b91da6b..569c145 100644
--- a/.github/workflows/pcgcli-pr.yml
+++ b/.github/workflows/pcgcli.yml
@@ -1,6 +1,9 @@
-name: Partitioned Consumer Groups CLI Pull Request
+name: Partitioned Consumer Groups CLI Build
on:
+ push:
+ branches:
+ - main
pull_request:
types: [opened, synchronize, reopened]
paths:
@@ -21,21 +24,32 @@ jobs:
- name: Check out code
uses: actions/checkout@v4
- name: Build with Gradle
- run: |
- chmod +x gradlew && ./gradlew clean test uberJar
+ run: chmod +x gradlew && ./gradlew clean dist
- name: Build with Maven
run: mvn clean package
- - name: Validate Gradle Uber was created
+ - name: Validate artifacts were created
run: |
- FILE_PATH="build/libs/cg.jar"
+ FILE_PATH="build/cg.jar"
+ if [ -f "$FILE_PATH" ]; then
+ echo "Validation successful: $FILE_PATH was created."
+ else
+ echo "Validation failed: $FILE_PATH was not found."
+ exit 1 # Fails the workflow step
+ fi
+ FILE_PATH="build/cg.zip"
+ if [ -f "$FILE_PATH" ]; then
+ echo "Validation successful: $FILE_PATH was created."
+ else
+ echo "Validation failed: $FILE_PATH was not found."
+ exit 1 # Fails the workflow step
+ fi
+ FILE_PATH="build/cg.tar"
if [ -f "$FILE_PATH" ]; then
echo "Validation successful: $FILE_PATH was created."
else
echo "Validation failed: $FILE_PATH was not found."
exit 1 # Fails the workflow step
fi
- - name: Validate Maven Uber was created
- run: |
FILE_PATH="target/cg.jar"
if [ -f "$FILE_PATH" ]; then
echo "Validation successful: $FILE_PATH was created."
diff --git a/pcgroups-cli/README.md b/pcgroups-cli/README.md
new file mode 100644
index 0000000..52014c5
--- /dev/null
+++ b/pcgroups-cli/README.md
@@ -0,0 +1,82 @@
+
+
+# Partitioned Consumer Groups CLI
+
+The Partitioned Consumer Groups CLI is a command line tool. In the usage,
+
+`cg` stands for `java -jar /cg.jar`
+
+```
+Usage: cg [options]
+
+Commands:
+ static Static consumer groups mode
+ elastic Elastic consumer groups mode
+
+Use 'cg --help' for more information about a command.
+```
+
+```
+Usage: cg static [COMMAND]
+Static consumer groups mode
+Commands:
+ ls, list List static consumer groups for a stream
+ info Get static consumer group info
+ create Create a static partitioned consumer group
+ delete, rm Delete a static partitioned consumer group
+ member-info, memberinfo, minfo Get static consumer group member info
+ step-down, stepdown, sd Initiate a step down for a member
+ consume, join Join a static partitioned consumer group
+ prompt Interactive prompt mode
+```
+
+```
+Usage: cg elastic [COMMAND]
+Elastic consumer groups mode
+Commands:
+ ls, list List elastic consumer groups for a stream
+ info Get elastic consumer group info
+ create Create an elastic partitioned consumer
+ group
+ delete, rm Delete an elastic partitioned consumer
+ group
+ add Add members to an elastic consumer group
+ drop Drop members from an elastic consumer group
+ create-mapping, cm, createmapping Create member mappings for an elastic
+ consumer group
+ delete-mapping, dm, deletemapping Delete member mappings for an elastic
+ consumer group
+ member-info, memberinfo, minfo Get elastic consumer group member info
+ step-down, stepdown, sd Initiate a step down for a member
+ consume, join Join an elastic partitioned consumer group
+ prompt Interactive prompt mode
+```
+
+## Building from Source
+The project contains both a Maven pom.xml file and a Gradle project,
+and both are configured to build an executable Java jar named `cg.jar`
+
+### Maven
+```
+mvn clean package
+```
+
+will build the `cg.jar` in the `target` folder
+
+### Gradle
+```
+gradle clean package
+```
+will build the `cg.jar` in the `build` folder
+
+## Running
+
+
+```
+java -jar target/cg.jar ...
+java -jar build/cg.jar ...
+```
+
+---
+Copyright (c) 2025 Synadia Communications Inc. All Rights Reserved.
+See [LICENSE](LICENSE) and [NOTICE](NOTICE) file for details.
diff --git a/pcgroups-cli/build.gradle b/pcgroups-cli/build.gradle
index 91d173f..094794d 100644
--- a/pcgroups-cli/build.gradle
+++ b/pcgroups-cli/build.gradle
@@ -1,17 +1,10 @@
plugins {
id("java")
- id("java-library")
- id("maven-publish")
- id("jacoco")
- id("biz.aQute.bnd.builder") version "7.1.0"
- id("org.gradle.test-retry") version "1.6.4"
- id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
- id("signing")
+ id 'com.github.johnrengelman.shadow' version '8.1.1' // Apply the shadow plugin
}
-group = 'io.synadia'
version = "0.1.0"
-def originalUber = 'pcg-cli-' + version + '-uber.jar'
+def originalShadow = 'pcg-cli-' + version + '-all.jar'
java {
sourceCompatibility = JavaVersion.VERSION_1_8
@@ -27,7 +20,7 @@ repositories {
dependencies {
implementation 'io.nats:jnats:2.25.1'
implementation 'org.jspecify:jspecify:1.0.0'
- implementation 'io.synadia:pcgroups:0.1.0-SNAPSHOT'
+ implementation 'io.synadia:pcgroups:0.1.0'
implementation 'info.picocli:picocli:4.7.5'
testImplementation 'io.nats:jnats-server-runner:3.1.0'
@@ -35,36 +28,39 @@ dependencies {
testImplementation 'org.junit.platform:junit-platform-launcher:1.14.3'
}
-tasks.register('copyToLib', Copy) {
- into "build/libs"
- from configurations.runtimeClasspath
+shadowJar {
+ manifest {
+ attributes 'Main-Class': 'io.synadia.pcg.cli.CgCommand'
+ }
}
-tasks.register('packageUberJar', Jar) {
- archiveClassifier = 'uber'
+tasks.register('package', Copy) {
+ dependsOn shadowJar
- from sourceSets.main.output
+ // we want the file to be called cg.jar
+ from ('build/libs')
+ include originalShadow
+ destinationDir file('build/')
+ rename originalShadow, "cg.jar"
+}
- dependsOn configurations.runtimeClasspath
- from {
- configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
- }
+tasks.register('createZip', Zip) {
+ dependsOn 'package'
- duplicatesStrategy = DuplicatesStrategy.EXCLUDE
- dependsOn copyToLib
+ archiveFileName = "cg.zip"
+ destinationDirectory = file('build/')
+ from (files('build/cg.jar'))
}
-tasks.register('uberJar', Copy) {
- dependsOn packageUberJar
+tasks.register('createTar', Tar) {
+ dependsOn 'package'
- // we want the file to be called cg.jar
- from ('build/libs')
- include originalUber
- destinationDir file('build/libs/')
- rename originalUber, "cg.jar"
+ archiveFileName = "cg.tar"
+ destinationDirectory = file('build/')
+ from (files('build/cg.jar'))
+}
- // this task actually does a copy, so this part removes the original
- doLast {
- delete('build/libs/' + originalUber)
- }
+tasks.register('dist') {
+ dependsOn createZip
+ dependsOn createTar
}
diff --git a/pcgroups/README.md b/pcgroups/README.md
index 331021d..e59ff56 100644
--- a/pcgroups/README.md
+++ b/pcgroups/README.md
@@ -2,9 +2,17 @@
# Partitioned Consumer Groups
+
+
+
+[](https://github.com/synadia-io/orbit.java?tab=readme-ov-file#dependencies)
+[](https://javadoc.io/doc/io.synadia/pcgroups)
+[](https://img.shields.io/maven-central/v/io.synadia/pcgroups)
+
Initial implementation of a client-side partitioned consumer group feature for NATS streams leveraging some of the new features introduced in `nats-server` version 2.11.
Note that post 2.11 versions of `nats-server` may include new features related to the consumer group use case that could render this client-side library unneeded (or make much smaller)
+
# Overview
This library enables the parallelization through partitioning of the consumption of messages from a stream while ensuring a strict order of not just delivery but also successful consumption of the messages using all or parts of the message's subject as a partitioning key.
@@ -54,6 +62,9 @@ Included is a small command line interface tool, named `cg` and located in the `
This `cg` CLI tool can be used by passing it commands and arguments directly, or with an interactive prompt using the `prompt` command (e.g. `cg static prompt`).
+For more details on the CLI visit the [Partitioned Consumer Groups CLI Project](https://github.com/synadia-io/orbit.java/tree/main/pcgroups-cli)
+
+
## Demo walkthrough
### Static
diff --git a/pcgroups/build.gradle b/pcgroups/build.gradle
index 75f3332..225e274 100644
--- a/pcgroups/build.gradle
+++ b/pcgroups/build.gradle
@@ -11,7 +11,7 @@ plugins {
id("signing")
}
-def jarVersion = "0.1.0"
+def jarVersion = "0.1.1"
group = 'io.synadia'
def isRelease = System.getenv("BUILD_EVENT") == "release"