NATS Logo by Example

List Subjects for a Specific Stream in JetStream

All clients have a way to get the list of subjects for any given stream, except it’s not completely obvious how to do this. These examples will show you how to get the list of subjects.

CLI Go Python JavaScript Rust C# .NET V2 Java Ruby Elixir Crystal C
Jump to the output or the recording
$ nbe run jetstream/list-subjects/java
View the source code or learn how to run this example yourself

Code

package example;


import io.nats.client.*;
import io.nats.client.api.*;


import java.io.IOException;
import java.util.Map;


public class Main {
  public static void main(String[] args) {
    String natsURL = System.getenv("NATS_URL");
    if (natsURL == null) {
      natsURL = "nats://127.0.0.1:4222";
    }


    try (Connection nc = Nats.connect(natsURL)) {
      JetStreamManagement jsm = nc.jetStreamManagement();
      JetStream js = jsm.jetStream();

Delete the stream, so we always have a fresh start for the example don’t care if this, errors in this example, it will if the stream exists.

      try {
        jsm.deleteStream("subjects");
      }
      catch (Exception ignore) {}

Create a stream with a few subjects

      jsm.addStream(StreamConfiguration.builder()
          .name("subjects")
          .subjects("plain", "greater.>", "star.*")
          .build());

GetStreamInfo with StreamInfoOptions

Get the subjects via the getStreamInfo call. Since this is “state” there are no subjects in the state unless there are messages in the subject.

      StreamInfo si = jsm.getStreamInfo("subjects", StreamInfoOptions.allSubjects());
      StreamState state = si.getStreamState();
      System.out.println("Before publishing any messages, there are 0 subjects: " + state.getSubjectCount());

Publish a message

      js.publish("plain", null);


      si = jsm.getStreamInfo("subjects", StreamInfoOptions.allSubjects());
      state = si.getStreamState();
      System.out.println("After publishing a message to a subject, it appears in state:");
      for (Subject s : state.getSubjects()) {
        System.out.println("  subject '" + s.getName() + "' has " + s.getCount() + " message(s)");
      }

Publish some more messages, this time against wildcard subjects

      js.publish("greater.A", "gtA-1".getBytes());
      js.publish("greater.A", "gtA-2".getBytes());
      js.publish("greater.A.B", "gtAB-1".getBytes());
      js.publish("greater.A.B", "gtAB-2".getBytes());
      js.publish("greater.A.B.C", "gtABC".getBytes());
      js.publish("greater.B.B.B", "gtBBB".getBytes());
      js.publish("star.1", "star1-1".getBytes());
      js.publish("star.1", "star1-2".getBytes());
      js.publish("star.2", "star2".getBytes());

Get all subjects, but get the subjects as a map, via getSubjectMap

      si = jsm.getStreamInfo("subjects", StreamInfoOptions.allSubjects());
      state = si.getStreamState();
      System.out.println("Wildcard subjects show the actual subject, not the template.");
      for (Map.Entry<String, Long> entry : state.getSubjectMap().entrySet()) {
        System.out.println("  subject '" + entry.getKey() + "' has " + entry.getValue() + " message(s)");
      }

Subject Filtering

Instead of allSubjects, you can filter for a specific subject

      si = jsm.getStreamInfo("subjects", StreamInfoOptions.filterSubjects("greater.>"));
      state = si.getStreamState();
      System.out.println("Filtering the subject returns only matching entries ['greater.>']");
      for (Subject s : state.getSubjects()) {
        System.out.println("  subject '" + s.getName() + "' has " + s.getCount() + " message(s)");
      }


      si = jsm.getStreamInfo("subjects", StreamInfoOptions.filterSubjects("greater.A.>"));
      state = si.getStreamState();
      System.out.println("Filtering the subject returns only matching entries ['greater.A.>']");
      for (Subject s : state.getSubjects()) {
        System.out.println("  subject '" + s.getName() + "' has " + s.getCount() + " message(s)");
      }
    } catch (InterruptedException | IOException | JetStreamApiException e) {
      e.printStackTrace();
    }
  }
}

Output

Before publishing any messages, there are 0 subjects: 0
After publishing a message to a subject, it appears in state:
  subject 'plain' has 1 message(s)
Wildcard subjects show the actual subject, not the template.
  subject 'greater.A' has 2 message(s)
  subject 'greater.B.B.B' has 1 message(s)
  subject 'greater.A.B' has 2 message(s)
  subject 'plain' has 1 message(s)
  subject 'star.1' has 2 message(s)
  subject 'star.2' has 1 message(s)
  subject 'greater.A.B.C' has 1 message(s)
Filtering the subject returns only matching entries ['greater.>']
  subject 'greater.A' has 2 message(s)
  subject 'greater.B.B.B' has 1 message(s)
  subject 'greater.A.B' has 2 message(s)
  subject 'greater.A.B.C' has 1 message(s)
Filtering the subject returns only matching entries ['greater.A.>']
  subject 'greater.A.B' has 2 message(s)
  subject 'greater.A.B.C' has 1 message(s)

Recording

Note, playback is half speed to make it a bit easier to follow.