Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2025 Synadia Communications Inc. All Rights Reserved.
// See LICENSE and NOTICE file for details.

package io.synadia.examples;

import io.nats.client.Connection;
import io.nats.client.JetStreamApiException;
import io.nats.client.JetStreamManagement;
import io.nats.client.Nats;
import io.nats.client.api.PublishAck;
import io.nats.client.api.StreamConfiguration;
import io.synadia.bp.BatchPublisher;

public class AtomicBatchDocExample {

Check warning on line 14 in batch-publish/src/examples/java/io/synadia/examples/AtomicBatchDocExample.java

View workflow job for this annotation

GitHub Actions / build

use of default constructor, which does not provide a comment

Check warning on line 14 in batch-publish/src/examples/java/io/synadia/examples/AtomicBatchDocExample.java

View workflow job for this annotation

GitHub Actions / build

no comment
static final String NATS_URL = "nats://localhost:4222";
static final String STREAM = "ORDERS";
static final String SUBJECTS = "orders.>";
static final String SUBJECT = "orders.created";
static final String BATCH_ID = "order-4273";

public static void main(String[] args) throws Exception {

Check warning on line 21 in batch-publish/src/examples/java/io/synadia/examples/AtomicBatchDocExample.java

View workflow job for this annotation

GitHub Actions / build

no comment
try (Connection nc = Nats.connect(NATS_URL)) {
JetStreamManagement jsm = nc.jetStreamManagement();

// Ensure an ORDERS stream exists with atomic batch publishing enabled.
try { jsm.deleteStream(STREAM); } catch (JetStreamApiException ignore) {}
StreamConfiguration config = StreamConfiguration.builder()
.name(STREAM)
.subjects(SUBJECTS)
.allowAtomicPublish()
.build();
jsm.addStream(config);

// NATS-DOC-START
// One order, three line items, stored as a single atomic batch:
// either all three messages land in the stream, or none do.
BatchPublisher publisher = BatchPublisher.builder()
.connection(nc)
.batchId(BATCH_ID)
.build();

publisher.add(SUBJECT, "{\"sku\":\"NATS-TEE\",\"qty\":2}".getBytes());
publisher.add(SUBJECT, "{\"sku\":\"NATS-MUG\",\"qty\":1}".getBytes());
PublishAck ack = publisher.commit(SUBJECT, "{\"sku\":\"NATS-CAP\",\"qty\":1}".getBytes());

System.out.println("Committed batch [" + publisher.getBatchId() + "]"
+ " of " + ack.getBatchSize() + " line items"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack.getBatchSize() is the only place this method is called in the entire examples codebase — existing examples use pa.getBatchId() and pa.getJv() but not getBatchSize(). Please confirm getBatchSize() exists on io.nats.client.api.PublishAck in jnats 2.25.1. If it's missing, the build will fail silently on this branch until CI runs the bp-* workflow. The rest of the line (getSeqno(), getBatchId()) are verified against other examples.

+ " at stream sequence " + ack.getSeqno() + ".");
// NATS-DOC-END
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2025 Synadia Communications Inc. All Rights Reserved.
// See LICENSE and NOTICE file for details.

package io.synadia.examples;

import io.nats.client.Connection;
import io.nats.client.JetStream;
import io.nats.client.JetStreamApiException;
import io.nats.client.JetStreamManagement;
import io.nats.client.Nats;
import io.nats.client.api.MessageInfo;
import io.nats.client.api.StreamConfiguration;
import io.synadia.direct.DirectBatchContext;
import io.synadia.direct.MessageBatchGetRequest;

import java.util.List;

public class LearnJetStreamGetDirectBatchGet {
static final String NATS_URL = System.getenv("NATS_URL") != null
? System.getenv("NATS_URL") : "nats://localhost:4222";
Comment on lines +19 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System.getenv("NATS_URL") is called twice. While env vars don't change mid-JVM, the double call is inconsistent with every other example in this repo (all of which hard-code the URL or use a single local variable). Consider either:

Suggested change
static final String NATS_URL = System.getenv("NATS_URL") != null
? System.getenv("NATS_URL") : "nats://localhost:4222";
static final String NATS_URL = "nats://localhost:4222";

or a static initializer with a single getenv call. The two-call form also makes it marginally harder to read at a glance.

static final String STREAM = "ORDERS";
static final String SUBJECTS = "orders.>";

public static void main(String[] args) throws Exception {
try (Connection nc = Nats.connect(NATS_URL)) {
JetStreamManagement jsm = nc.jetStreamManagement();
JetStream js = nc.jetStream();

// Ensure an ORDERS stream exists with direct access enabled,
// then seed a few orders so the batch get has something to read.
try { jsm.deleteStream(STREAM); } catch (JetStreamApiException ignore) {}
jsm.addStream(StreamConfiguration.builder()
.name(STREAM)
.subjects(SUBJECTS)
.allowDirect(true)
.build());

js.publish("orders.created", "{\"id\":\"order-1\"}".getBytes());
js.publish("orders.created", "{\"id\":\"order-2\"}".getBytes());
js.publish("orders.created", "{\"id\":\"order-3\"}".getBytes());

// NATS-DOC-START
// Batch Direct Get: in one request, read up to 3 messages from the
// ORDERS stream starting at stream sequence 1, then iterate in order.
DirectBatchContext direct = new DirectBatchContext(nc, STREAM);
MessageBatchGetRequest request = MessageBatchGetRequest.batch(">", 3, 1);

List<MessageInfo> messages = direct.fetchMessageBatch(request);
for (MessageInfo mi : messages) {
System.out.println("sequence " + mi.getSeq() + " | subject " + mi.getSubject());
}
// NATS-DOC-END
}
}
}
Loading