diff --git a/build.gradle b/build.gradle index 32452e406..0e23ff143 100644 --- a/build.gradle +++ b/build.gradle @@ -98,12 +98,18 @@ test { javadoc { options.overview = 'src/main/javadoc/overview.html' // relative to source root + options.memberLevel = JavadocMemberLevel.PUBLIC source = sourceSets.main.allJava title = "NATS.IO Java API" - excludes = ['io/nats/client/impl', - 'io/nats/examples', - "io/nats/client/api/ConsumerCreateRequest.java", - "io/nats/client/api/MessageGetRequest.java" + excludes = [ + "io/nats/client/impl", + "io/nats/examples", + "io/nats/client/api/ConsumerCreateRequest.java", + "io/nats/client/api/MessageGetRequest.java", + "io/nats/client/api/MessageDeleteRequest.java", + "io/nats/client/support/IncomingHeadersProcessor.java", + "io/nats/client/support/**", + "**/Debug**" ] classpath = sourceSets.main.runtimeClasspath doLast { diff --git a/src/main/java/io/nats/client/BaseConsumeOptions.java b/src/main/java/io/nats/client/BaseConsumeOptions.java index 261d0a17f..94d7a4d78 100644 --- a/src/main/java/io/nats/client/BaseConsumeOptions.java +++ b/src/main/java/io/nats/client/BaseConsumeOptions.java @@ -31,12 +31,19 @@ * fetch operate. It is the base class for ConsumeOptions and FetchConsumeOptions. */ public class BaseConsumeOptions implements JsonSerializable { + /** constant for default message count */ public static final int DEFAULT_MESSAGE_COUNT = 500; + /** constant for default message count when bytes */ public static final int DEFAULT_MESSAGE_COUNT_WHEN_BYTES = 1_000_000; + /** constant for default threshold percent */ public static final int DEFAULT_THRESHOLD_PERCENT = 25; + /** constant for default expires in millis */ public static final long DEFAULT_EXPIRES_IN_MILLIS = 30000; + /** constant for min expires mills */ public static final long MIN_EXPIRES_MILLS = 1000; + /** constant for max heartbeat millis */ public static final long MAX_HEARTBEAT_MILLIS = 30000; + /** constant for max idle heartbeat percent */ public static final int MAX_IDLE_HEARTBEAT_PERCENT = 50; protected final int messages; @@ -94,34 +101,66 @@ public String toJson() { protected void subclassSpecificToJson(StringBuilder sb) {} + /** + * Get the expires setting + * @return the expires, in milliseconds + */ public long getExpiresInMillis() { return expiresIn; } + /** + * Get the idle heartbeat value + * @return the idle heartbeat in milliseconds + */ public long getIdleHeartbeat() { return idleHeartbeat; } + /** + * Get the threshold percent setting + * @return the threshold percent + */ public int getThresholdPercent() { return thresholdPercent; } + /** + * Whether to raise status warnings to the error listener + * @return true if should raise status warnings + */ public boolean raiseStatusWarnings() { return raiseStatusWarnings; } + /** + * Get the priority group setting + * @return the priority group + */ public String getGroup() { return group; } + /** + * Get the priority setting + * @return the priority + */ public int getPriority() { return priority; } + /** + * Get the min pending setting + * @return the min pending + */ public long getMinPending() { return minPending; } + /** + * Get the min ack pending setting + * @return the min ack pending + */ public long getMinAckPending() { return minAckPending; } @@ -143,7 +182,7 @@ protected static abstract class Builder { * Initialize values from the json string. * @param json the json string to parse * @return the builder - * @throws JsonParseException if the json is invalid + * @throws JsonParseException if there is a problem parsing the json */ public B json(String json) throws JsonParseException { return jsonValue(JsonParser.parse(json)); diff --git a/src/main/java/io/nats/client/Connection.java b/src/main/java/io/nats/client/Connection.java index c84ca6e7e..b287c4c05 100644 --- a/src/main/java/io/nats/client/Connection.java +++ b/src/main/java/io/nats/client/Connection.java @@ -1,806 +1,815 @@ -// Copyright 2015-2018 The NATS Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package io.nats.client; - -import io.nats.client.api.ServerInfo; -import io.nats.client.impl.Headers; -import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; - -import java.io.IOException; -import java.net.InetAddress; -import java.time.Duration; -import java.util.Collection; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeoutException; - -/** - * The Connection class is at the heart of the NATS Java client. Fundamentally a connection represents - * a single network connection to the NATS server. - * - *

Each connection you create will result in the creation of a single socket and several threads: - *

- * - *

The connection has a {@link Connection.Status status} which can be checked using the {@link #getStatus() getStatus} - * method or watched using a {@link ConnectionListener ConnectionListener}. - * - *

Connections, by default, are configured to try to reconnect to the server if there is a network failure up to - * {@link Options#DEFAULT_MAX_RECONNECT times}. You can configure this behavior in the {@link Options Options}. - * Moreover, the options allows you to control whether reconnect happens in the same order every time, and the time - * to wait if trying to reconnect to the same server over and over. - * - *

The list of servers used for connecting is provided by the {@link Options Options}. The list of servers used - * during reconnect can be an expanded list. This expansion comes from the connections most recent server. For example, - * if you connect to serverA, it can tell the connection "i know about serverB and serverC". If serverA goes down - * the client library will try to connect to serverA, serverB and serverC. Now, if the library connects to serverB, it may tell the client - * "i know about serverB and serverE". The client's list of servers, available from {@link #getServers() getServers()} - * will now be serverA from the initial connect, serverB and serverE, the reference to serverC is lost. - * - *

When a connection is {@link #close() closed} the thread and socket resources are cleaned up. - * - *

All outgoing messages are sent through the connection object using one of the two - * {@link #publish(String, byte[]) publish} methods or the {@link #request(String, byte[]) request} method. - * When publishing you can specify a reply to subject which can be retrieved by the receiver to respond. - * The request method will handle this behavior itself, but it relies on getting the value out of a Future - * so may be less flexible than publish with replyTo set. - * - *

Messages can be received in two ways. You can create a Subscription which will allow you to read messages - * synchronously using the {@link Subscription#nextMessage(Duration) nextMessage} method or you can create a - * {@link Dispatcher Dispatcher}. The Dispatcher will create a thread to listen for messages on one or more subscriptions. - * The Dispatcher groups a set of subscriptions into a single listener thread that calls application code - * for each messages. - * - *

Applications can use the {@link #flush(Duration) flush} method to check that published messages have - * made it to the server. However, this method initiates a round trip to the server and waits for the response so - * it should be used sparingly. - * - *

The connection provides two listeners via the Options. The {@link ConnectionListener ConnectionListener} - * can be used to listen for lifecycle events. This listener is required for - * {@link Nats#connectAsynchronously(Options, boolean) connectAsynchronously}, but otherwise optional. The - * {@link ErrorListener ErrorListener} provides three callback opportunities including slow consumers, error - * messages from the server and exceptions handled by the client library. These listeners can only be set at creation time - * using the {@link Options options}. - * - *

Note: The publish methods take an array of bytes. These arrays will not be copied. This design choice - * is based on the common case of strings or objects being converted to bytes. Once a client can be sure a message was received by - * the NATS server it is theoretically possible to reuse that byte array, but this pattern should be treated as advanced and only used - * after thorough testing. - */ -public interface Connection extends AutoCloseable { - - enum Status { - /** - * The {@code Connection} is not connected. - */ - DISCONNECTED, - /** - * The {@code Connection} is currently connected. - */ - CONNECTED, - /** - * The {@code Connection} is currently closed. - */ - CLOSED, - /** - * The {@code Connection} is currently attempting to reconnect to a server from its server list. - */ - RECONNECTING, - /** - * The {@code Connection} is currently connecting to a server for the first - * time. - */ - CONNECTING; - } - - /** - * Send a message to the specified subject. The message body will - * not be copied. The expected usage with string content is something - * like: - * - *

-     * nc = Nats.connect()
-     * nc.publish("destination", "message".getBytes("UTF-8"))
-     * 
- * - * where the sender creates a byte array immediately before calling publish. - * See {@link #publish(String, String, byte[]) publish()} for more details on - * publish during reconnect. - * - * @param subject the subject to send the message to - * @param body the message body - * @throws IllegalStateException if the reconnect buffer is exceeded - */ - void publish(@NonNull String subject, byte @Nullable [] body); - - /** - * Send a message to the specified subject. The message body will - * not be copied. The expected usage with string content is something - * like: - * - *
-     * nc = Nats.connect()
-     * Headers h = new Headers().put("key", "value");
-     * nc.publish("destination", h, "message".getBytes("UTF-8"))
-     * 
- * - * where the sender creates a byte array immediately before calling publish. - * See {@link #publish(String, String, byte[]) publish()} for more details on - * publish during reconnect. - * - * @param subject the subject to send the message to - * @param headers Optional headers to publish with the message. - * @param body the message body - * @throws IllegalStateException if the reconnect buffer is exceeded - */ - void publish(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body); - - /** - * Send a request to the specified subject, providing a replyTo subject. The - * message body will not be copied. The expected usage with - * string content is something like: - * - *
-     * nc = Nats.connect()
-     * nc.publish("destination", "reply-to", "message".getBytes("UTF-8"))
-     * 
- * - * where the sender creates a byte array immediately before calling publish. - *

- * During reconnect the client will try to buffer messages. The buffer size is set - * in the connect options, see {@link Options.Builder#reconnectBufferSize(long) reconnectBufferSize()} - * with a default value of {@link Options#DEFAULT_RECONNECT_BUF_SIZE 8 * 1024 * 1024} bytes. - * If the buffer is exceeded an IllegalStateException is thrown. Applications should use - * this exception as a signal to wait for reconnect before continuing. - *

- * @param subject the subject to send the message to - * @param replyTo the subject the receiver should send any response to - * @param body the message body - * @throws IllegalStateException if the reconnect buffer is exceeded - */ - void publish(@NonNull String subject, @Nullable String replyTo, byte @Nullable [] body); - - /** - * Send a request to the specified subject, providing a replyTo subject. The - * message body will not be copied. The expected usage with - * string content is something like: - * - *
-     * nc = Nats.connect()
-     * Headers h = new Headers().put("key", "value");
-     * nc.publish("destination", "reply-to", h, "message".getBytes("UTF-8"))
-     * 
- * - * where the sender creates a byte array immediately before calling publish. - *

- * During reconnect the client will try to buffer messages. The buffer size is set - * in the connect options, see {@link Options.Builder#reconnectBufferSize(long) reconnectBufferSize()} - * with a default value of {@link Options#DEFAULT_RECONNECT_BUF_SIZE 8 * 1024 * 1024} bytes. - * If the buffer is exceeded an IllegalStateException is thrown. Applications should use - * this exception as a signal to wait for reconnect before continuing. - *

- * @param subject the subject to send the message to - * @param replyTo the subject the receiver should send any response to - * @param headers Optional headers to publish with the message. - * @param body the message body - * @throws IllegalStateException if the reconnect buffer is exceeded - */ - void publish(@NonNull String subject, @Nullable String replyTo, @Nullable Headers headers, byte @Nullable [] body); - - /** - * Send a message to the specified subject. The message body will - * not be copied. The expected usage with string content is something - * like: - * - *
-     * nc = Nats.connect()
-     * nc.publish(NatsMessage.builder()...build())
-     * 
- * - * where the sender creates a byte array immediately before calling publish. - * See {@link #publish(String, String, byte[]) publish()} for more details on - * publish during reconnect. - * - * @param message the message - * @throws IllegalStateException if the reconnect buffer is exceeded - */ - void publish(@NonNull Message message); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - * @param subject the subject for the service that will handle the request - * @param body the content of the message - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture request(@NonNull String subject, byte @Nullable [] body); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - * @param subject the subject for the service that will handle the request - * @param headers Optional headers to publish with the message. - * @param body the content of the message - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture request(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - * @param subject the subject for the service that will handle the request - * @param body the content of the message - * @param timeout the time to wait for a response. If not supplied a default will be used. - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture requestWithTimeout(@NonNull String subject, byte @Nullable [] body, @Nullable Duration timeout); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - * @param subject the subject for the service that will handle the request - * @param body the content of the message - * @param headers Optional headers to publish with the message. - * @param timeout the time to wait for a response - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture requestWithTimeout(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body, Duration timeout); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - *

The Message object allows you to set a replyTo, but in requests, - * the replyTo is reserved for internal use as the address for the - * server to respond to the client with the consumer's reply.

- * - * @param message the message - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture request(@NonNull Message message); - - /** - * Send a request. The returned future will be completed when the - * response comes back. - * - *

The Message object allows you to set a replyTo, but in requests, - * the replyTo is reserved for internal use as the address for the - * server to respond to the client with the consumer's reply.

- * - * @param message the message - * @param timeout the time to wait for a response - * @return a Future for the response, which may be cancelled on error or timed out - */ - @NonNull - CompletableFuture requestWithTimeout(@NonNull Message message, @Nullable Duration timeout); - - /** - * Send a request and returns the reply or null. This version of request is equivalent - * to calling get on the future returned from {@link #request(String, byte[]) request()} with - * the timeout and handling the ExecutionException and TimeoutException. - * - * @param subject the subject for the service that will handle the request - * @param body the content of the message - * @param timeout the time to wait for a response - * @return the reply message or null if the timeout is reached - * @throws InterruptedException if one is thrown while waiting, in order to propagate it up - */ - @Nullable - Message request(@NonNull String subject, byte @Nullable [] body, @Nullable Duration timeout) throws InterruptedException; - - /** - * Send a request and returns the reply or null. This version of request is equivalent - * to calling get on the future returned from {@link #request(String, byte[]) request()} with - * the timeout and handling the ExecutionException and TimeoutException. - * - * @param subject the subject for the service that will handle the request - * @param headers Optional headers to publish with the message. - * @param body the content of the message - * @param timeout the time to wait for a response - * @return the reply message or null if the timeout is reached - * @throws InterruptedException if one is thrown while waiting, in order to propagate it up - */ - @Nullable - Message request(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body, @Nullable Duration timeout) throws InterruptedException; - - /** - * Send a request and returns the reply or null. This version of request is equivalent - * to calling get on the future returned from {@link #request(String, byte[]) request()} with - * the timeout and handling the ExecutionException and TimeoutException. - * - *

The Message object allows you to set a replyTo, but in requests, - * the replyTo is reserved for internal use as the address for the - * server to respond to the client with the consumer's reply.

- * - * @param message the message - * @param timeout the time to wait for a response - * @return the reply message or null if the timeout is reached - * @throws InterruptedException if one is thrown while waiting, in order to propagate it up - */ - @Nullable - Message request(@NonNull Message message, @Nullable Duration timeout) throws InterruptedException; - - /** - * Create a synchronous subscription to the specified subject. - * - *

Use the {@link io.nats.client.Subscription#nextMessage(Duration) nextMessage} - * method to read messages for this subscription. - * - *

See {@link #createDispatcher(MessageHandler) createDispatcher} for - * information about creating an asynchronous subscription with callbacks. - * - *

As of 2.6.1 this method will throw an IllegalArgumentException if the subject contains whitespace. - * - * @param subject the subject to subscribe to - * @return an object representing the subscription - */ - @NonNull - Subscription subscribe(@NonNull String subject); - - /** - * Create a synchronous subscription to the specified subject and queue. - * - *

Use the {@link Subscription#nextMessage(Duration) nextMessage} method to read - * messages for this subscription. - * - *

See {@link #createDispatcher(MessageHandler) createDispatcher} for - * information about creating an asynchronous subscription with callbacks. - * - *

As of 2.6.1 this method will throw an IllegalArgumentException if either string contains whitespace. - * - * @param subject the subject to subscribe to - * @param queueName the queue group to join - * @return an object representing the subscription - */ - @NonNull - Subscription subscribe(@NonNull String subject, @NonNull String queueName); - - /** - * Create a {@code Dispatcher} for this connection. The dispatcher can group one - * or more subscriptions into a single callback thread. All messages go to the - * same {@code MessageHandler}. - * - *

Use the Dispatcher's {@link Dispatcher#subscribe(String)} and - * {@link Dispatcher#subscribe(String, String)} methods to add subscriptions. - * - *

-     * nc = Nats.connect()
-     * d = nc.createDispatcher((m) -> System.out.println(m)).subscribe("hello");
-     * 
- * - * @param handler The target for the messages. If the handler is null, subscribing without - * using its API that accepts a handler will discard messages. - * @return a new Dispatcher - */ - @NonNull - Dispatcher createDispatcher(@Nullable MessageHandler handler); - - /** - * Convenience method to create a dispatcher with no default handler. Only used - * with JetStream push subscriptions that require specific handlers per subscription. - * - * @return a new Dispatcher - */ - @NonNull - Dispatcher createDispatcher(); - - /** - * Close a dispatcher. This will unsubscribe any subscriptions and stop the delivery thread. - * - *

Once closed the dispatcher will throw an exception on subsequent subscribe or unsubscribe calls. - * - * @param dispatcher the dispatcher to close - */ - void closeDispatcher(@NonNull Dispatcher dispatcher); - - /** - * Attach another ConnectionListener. - * - *

The ConnectionListener will only receive Connection events arriving after it has been attached. When - * a Connection event is raised, the invocation order and parallelism of multiple ConnectionListeners is not - * specified. - * - * @param connectionListener the ConnectionListener to attach. A null listener is a no-op - */ - void addConnectionListener(@NonNull ConnectionListener connectionListener); - - /** - * Detach a ConnectionListioner. This will cease delivery of any further Connection events to this instance. - * - * @param connectionListener the ConnectionListener to detach - */ - void removeConnectionListener(@NonNull ConnectionListener connectionListener); - - /** - * Flush the connection's buffer of outgoing messages, including sending a - * protocol message to and from the server. Passing null is equivalent to - * passing 0, which will wait forever. - * If called while the connection is closed, this method will immediately - * throw a TimeoutException, regardless of the timeout. - * If called while the connection is disconnected due to network issues this - * method will wait for up to the timeout for a reconnect or close. - * - * @param timeout The time to wait for the flush to succeed, pass 0 or null to wait forever. - * @throws TimeoutException if the timeout is exceeded - * @throws InterruptedException if the underlying thread is interrupted - */ - void flush(@Nullable Duration timeout) throws TimeoutException, InterruptedException; - - /** - * Drain tells the connection to process in flight messages before closing. - * Drain initially drains all the consumers, stopping incoming messages. - * Next, publishing is halted and a flush call is used to insure all published - * messages have reached the server. - * Finally, the connection is closed. - * In order to drain subscribers, an unsub protocol message is sent to the server followed by a flush. - * These two steps occur before drain returns. The remaining steps occur in a background thread. - * This method tries to manage the timeout properly, so that if the timeout is 1 second, and the flush - * takes 100ms, the remaining steps have 900ms in the background thread. - * The connection will try to let all messages be drained, but when the timeout is reached - * the connection is closed and any outstanding dispatcher threads are interrupted. - * A future allows this call to be treated as synchronous or asynchronous as - * needed by the application. The value of the future will be true if all the subscriptions - * were drained in the timeout, and false otherwise. The future completes after the connection - * is closed, so any connection handler notifications will happen before the future completes. - * - * @param timeout The time to wait for the drain to succeed, pass 0 or null to wait - * forever. Drain involves moving messages to and from the server - * so a very short timeout is not recommended. If the timeout is reached before - * the drain completes, the connection is simply closed, which can result in message - * loss. - * @return A future that can be used to check if the drain has completed - * @throws InterruptedException if the thread is interrupted - * @throws TimeoutException if the initial flush times out - */ - @NonNull - CompletableFuture drain(@Nullable Duration timeout) throws TimeoutException, InterruptedException; - - /** - * Close the connection and release all blocking calls like {@link #flush flush} - * and {@link Subscription#nextMessage(Duration) nextMessage}. - * If close() is called after {@link #drain(Duration) drain} it will wait up to the connection timeout - * to return, but it will not initiate a close. The drain takes precedence and will initiate the close. - * - * @throws InterruptedException if the thread, or one owned by the connection is interrupted during the close - */ - void close() throws InterruptedException ; - - /** - * Returns the connections current status. - * - * @return the connection's status - */ - @NonNull - Status getStatus(); - - /** - * MaxPayload returns the size limit that a message payload can have. This is - * set by the server configuration and delivered to the client upon connect. - * - * @return the maximum size of a message payload - */ - long getMaxPayload(); - - /** - * Return the list of known server urls, including additional servers discovered - * after a connection has been established. - * Will be empty (but not null) before a connection is made and will represent the last connected server while disconnected - * @return this connection's list of known server URLs - */ - @NonNull - Collection getServers(); - - /** - * @return a wrapper for useful statistics about the connection - */ - @NonNull - Statistics getStatistics(); - - /** - * @return the read-only options used to create this connection - */ - @NonNull - Options getOptions(); - - /** - * Return the server info object. Will never be null, but will be an instance of {@link ServerInfo#EMPTY_INFO} - * before a connection is made, and will represent the last connected server once connected and while disconnected - * until a new connection is made. - * @return the server information such as id, client info, etc. - */ - @NonNull - ServerInfo getServerInfo(); - - /** - * @return the url used for the current connection, or null if disconnected - */ - @Nullable - String getConnectedUrl(); - - /** - * @return the InetAddress of client as known by the NATS server, otherwise null. - */ - @Nullable - InetAddress getClientInetAddress(); - - /** - * @return the error text from the last error sent by the server to this client - */ - @Nullable - String getLastError(); - - /** - * Clear the last error from the server - */ - void clearLastError(); - - /** - * @return a new inbox subject, can be used for directed replies from - * subscribers. These are guaranteed to be unique, but can be shared and subscribed - * to by others. - */ - @NonNull - String createInbox(); - - /** - * Immediately flushes the underlying connection buffer if the connection is valid. - * @throws IOException if the connection flush fails - */ - void flushBuffer() throws IOException; - - /** - * Forces reconnect behavior. Stops the current connection including the reading and writing, - * copies already queued outgoing messages, and then begins the reconnect logic. - * Does not flush. Does not force close the connection. See {@link ForceReconnectOptions}. - * @throws IOException the forceReconnect fails - * @throws InterruptedException the connection is not connected - */ - void forceReconnect() throws IOException, InterruptedException; - - /** - * Forces reconnect behavior. Stops the current connection including the reading and writing, - * copies already queued outgoing messages, and then begins the reconnect logic. - * If options are not provided, the default options are used meaning Does not flush and Does not force close the connection. - * See {@link ForceReconnectOptions}. - * @param options options for how the forceReconnect works. - * @throws IOException the forceReconnect fails - * @throws InterruptedException the connection is not connected - */ - void forceReconnect(@Nullable ForceReconnectOptions options) throws IOException, InterruptedException; - - /** - * Calculates the round trip time between this client and the server. - * @return the RTT as a duration - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - Duration RTT() throws IOException; - - /** - * Get a stream context for a specific stream. - * - *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} - * @param streamName the stream for the context - * @return a StreamContext instance. - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - * @throws JetStreamApiException the request had an error related to the data - */ - @NonNull - StreamContext getStreamContext(@NonNull String streamName) throws IOException, JetStreamApiException; - - /** - * Get a stream context for a specific stream - *

Recommended: {@link StreamContext StreamContext} and {@link ConsumerContext ConsumerContext} are the preferred way to interact with existing streams and consume from streams. - * {@link JetStreamManagement JetStreamManagement} should be used to create streams and consumers. {@link ConsumerContext#consume ConsumerContext.consume()} supports both push and pull consumers transparently. - * - *

-     * nc = Nats.connect();
-	 * StreamContext streamContext = nc.getStreamContext("my-stream");
-	 * ConsumerContext consumerContext = streamContext.getConsumerContext("my-consumer");
-	 * // Or directly: 
-	 * // ConsumerContext consumerContext = nc.getConsumerContext("my-stream", "my-consumer"); 
-	 * consumerContext.consume(
-	 *      	msg -> {
-	 *             System.out.println("   Received " + msg.getSubject());
-	 *             msg.ack();
-	 *           });
-	   
- * - * @param streamName the stream for the context - * @param options JetStream options. If null, default / no options are used. - * @return a StreamContext instance. - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - * @throws JetStreamApiException the request had an error related to the data - */ - @NonNull - StreamContext getStreamContext(@NonNull String streamName, @Nullable JetStreamOptions options) throws IOException, JetStreamApiException; - - /** - * Get a consumer context for a specific named stream and specific named consumer. - * Verifies that the stream and consumer exist. - * - *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} - * - * @param streamName the name of the stream - * @param consumerName the name of the consumer - * @return a ConsumerContext object - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - * @throws JetStreamApiException the request had an error related to the data - */ - @NonNull - ConsumerContext getConsumerContext(@NonNull String streamName, @NonNull String consumerName) throws IOException, JetStreamApiException; - - /** - * Get a consumer context for a specific named stream and specific named consumer. - * Verifies that the stream and consumer exist. - * - *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} - * - * @param streamName the name of the stream - * @param consumerName the name of the consumer - * @param options JetStream options. If null, default / no options are used. - * @return a ConsumerContext object - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - * @throws JetStreamApiException the request had an error related to the data - */ - @NonNull - ConsumerContext getConsumerContext(@NonNull String streamName, @NonNull String consumerName, @Nullable JetStreamOptions options) throws IOException, JetStreamApiException; - - /** - * Gets a context for publishing and subscribing to subjects backed by Jetstream streams - * and consumers. - * @return a JetStream instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - JetStream jetStream() throws IOException; - - /** - * Gets a context for publishing and subscribing to subjects backed by Jetstream streams - * and consumers. - * @param options JetStream options. If null, default / no options are used. - * @return a JetStream instance. - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - */ - @NonNull - JetStream jetStream(@Nullable JetStreamOptions options) throws IOException; - - /** - * Gets a context for managing Jetstream streams - * and consumers. - * @return a JetStreamManagement instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - JetStreamManagement jetStreamManagement() throws IOException; - - /** - * Gets a context for managing Jetstream streams - * and consumers. - * @param options JetStream options. If null, default / no options are used. - * @return a JetStreamManagement instance. - * @throws IOException covers various communication issues with the NATS - * server such as timeout or interruption - */ - @NonNull - JetStreamManagement jetStreamManagement(@Nullable JetStreamOptions options) throws IOException; - - /** - * Gets a context for working with a Key Value bucket - * @param bucketName the bucket name - * @return a KeyValue instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - KeyValue keyValue(@NonNull String bucketName) throws IOException; - - /** - * Gets a context for working with a Key Value bucket - * @param bucketName the bucket name - * @param options KeyValue options. If null, default / no options are used. - * @return a KeyValue instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - KeyValue keyValue(@NonNull String bucketName, @Nullable KeyValueOptions options) throws IOException; - - /** - * Gets a context for managing Key Value buckets - * @return a KeyValueManagement instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - KeyValueManagement keyValueManagement() throws IOException; - - /** - * Gets a context for managing Key Value buckets - * @param options KeyValue options. If null, default / no options are used. - * @return a KeyValueManagement instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - KeyValueManagement keyValueManagement(@Nullable KeyValueOptions options) throws IOException; - - /** - * Gets a context for working with an Object Store. - * @param bucketName the bucket name - * @return an ObjectStore instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - ObjectStore objectStore(@NonNull String bucketName) throws IOException; - - /** - * Gets a context for working with an Object Store. - * @param bucketName the bucket name - * @param options ObjectStore options. If null, default / no options are used. - * @return an ObjectStore instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - ObjectStore objectStore(@NonNull String bucketName, @Nullable ObjectStoreOptions options) throws IOException; - - /** - * Gets a context for managing Object Stores - * @return an ObjectStoreManagement instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - ObjectStoreManagement objectStoreManagement() throws IOException; - - /** - * Gets a context for managing Object Stores - * @param options ObjectStore options. If null, default / no options are used. - * @return a ObjectStoreManagement instance. - * @throws IOException various IO exception such as timeout or interruption - */ - @NonNull - ObjectStoreManagement objectStoreManagement(ObjectStoreOptions options) throws IOException; - - /** - * Get the number of messages in the outgoing queue for this connection. - * This value is volatile in the sense that it changes often and may be adjusted by more than one message. - * It changes every time a message is published (put in the outgoing queue) - * and every time a message is removed from the queue to be written over the socket - * @return the number of messages in the outgoing queue - */ - long outgoingPendingMessageCount(); - - /** - * Get the number of bytes based to be written calculated from the messages in the outgoing queue for this connection. - * This value is volatile in the sense that it changes often and may be adjusted by more than one message's bytes. - * It changes every time a message is published (put in the outgoing queue) - * and every time a message is removed from the queue to be written over the socket - * @return the number of messages in the outgoing queue - */ - long outgoingPendingBytes(); -} +// Copyright 2015-2018 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io.nats.client; + +import io.nats.client.api.ServerInfo; +import io.nats.client.impl.Headers; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.io.IOException; +import java.net.InetAddress; +import java.time.Duration; +import java.util.Collection; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeoutException; + +/** + * The Connection class is at the heart of the NATS Java client. Fundamentally a connection represents + * a single network connection to the NATS server. + * + *

Each connection you create will result in the creation of a single socket and several threads: + *

    + *
  • A reader thread for taking data off the socket + *
  • A writer thread for putting data onto the socket + *
  • A timer thread for a few maintenance timers + *
  • A dispatch thread to handle request/reply traffic + *
+ * + *

The connection has a {@link Connection.Status status} which can be checked using the {@link #getStatus() getStatus} + * method or watched using a {@link ConnectionListener ConnectionListener}. + * + *

Connections, by default, are configured to try to reconnect to the server if there is a network failure up to + * {@link Options#DEFAULT_MAX_RECONNECT times}. You can configure this behavior in the {@link Options Options}. + * Moreover, the options allows you to control whether reconnect happens in the same order every time, and the time + * to wait if trying to reconnect to the same server over and over. + * + *

The list of servers used for connecting is provided by the {@link Options Options}. The list of servers used + * during reconnect can be an expanded list. This expansion comes from the connections most recent server. For example, + * if you connect to serverA, it can tell the connection "i know about serverB and serverC". If serverA goes down + * the client library will try to connect to serverA, serverB and serverC. Now, if the library connects to serverB, it may tell the client + * "i know about serverB and serverE". The client's list of servers, available from {@link #getServers() getServers()} + * will now be serverA from the initial connect, serverB and serverE, the reference to serverC is lost. + * + *

When a connection is {@link #close() closed} the thread and socket resources are cleaned up. + * + *

All outgoing messages are sent through the connection object using one of the two + * {@link #publish(String, byte[]) publish} methods or the {@link #request(String, byte[]) request} method. + * When publishing you can specify a reply to subject which can be retrieved by the receiver to respond. + * The request method will handle this behavior itself, but it relies on getting the value out of a Future + * so may be less flexible than publish with replyTo set. + * + *

Messages can be received in two ways. You can create a Subscription which will allow you to read messages + * synchronously using the {@link Subscription#nextMessage(Duration) nextMessage} method or you can create a + * {@link Dispatcher Dispatcher}. The Dispatcher will create a thread to listen for messages on one or more subscriptions. + * The Dispatcher groups a set of subscriptions into a single listener thread that calls application code + * for each messages. + * + *

Applications can use the {@link #flush(Duration) flush} method to check that published messages have + * made it to the server. However, this method initiates a round trip to the server and waits for the response so + * it should be used sparingly. + * + *

The connection provides two listeners via the Options. The {@link ConnectionListener ConnectionListener} + * can be used to listen for lifecycle events. This listener is required for + * {@link Nats#connectAsynchronously(Options, boolean) connectAsynchronously}, but otherwise optional. The + * {@link ErrorListener ErrorListener} provides three callback opportunities including slow consumers, error + * messages from the server and exceptions handled by the client library. These listeners can only be set at creation time + * using the {@link Options options}. + * + *

Note: The publish methods take an array of bytes. These arrays will not be copied. This design choice + * is based on the common case of strings or objects being converted to bytes. Once a client can be sure a message was received by + * the NATS server it is theoretically possible to reuse that byte array, but this pattern should be treated as advanced and only used + * after thorough testing. + */ +public interface Connection extends AutoCloseable { + + /** + * Enum representing the status of a connection + */ + enum Status { + /** + * The {@code Connection} is not connected. + */ + DISCONNECTED, + /** + * The {@code Connection} is currently connected. + */ + CONNECTED, + /** + * The {@code Connection} is currently closed. + */ + CLOSED, + /** + * The {@code Connection} is currently attempting to reconnect to a server from its server list. + */ + RECONNECTING, + /** + * The {@code Connection} is currently connecting to a server for the first + * time. + */ + CONNECTING; + } + + /** + * Send a message to the specified subject. The message body will + * not be copied. The expected usage with string content is something + * like: + * + *

+     * nc = Nats.connect()
+     * nc.publish("destination", "message".getBytes("UTF-8"))
+     * 
+ * + * where the sender creates a byte array immediately before calling publish. + * See {@link #publish(String, String, byte[]) publish()} for more details on + * publish during reconnect. + * + * @param subject the subject to send the message to + * @param body the message body + * @throws IllegalStateException if the reconnect buffer is exceeded + */ + void publish(@NonNull String subject, byte @Nullable [] body); + + /** + * Send a message to the specified subject. The message body will + * not be copied. The expected usage with string content is something + * like: + * + *
+     * nc = Nats.connect()
+     * Headers h = new Headers().put("key", "value");
+     * nc.publish("destination", h, "message".getBytes("UTF-8"))
+     * 
+ * + * where the sender creates a byte array immediately before calling publish. + * See {@link #publish(String, String, byte[]) publish()} for more details on + * publish during reconnect. + * + * @param subject the subject to send the message to + * @param headers Optional headers to publish with the message. + * @param body the message body + * @throws IllegalStateException if the reconnect buffer is exceeded + */ + void publish(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body); + + /** + * Send a request to the specified subject, providing a replyTo subject. The + * message body will not be copied. The expected usage with + * string content is something like: + * + *
+     * nc = Nats.connect()
+     * nc.publish("destination", "reply-to", "message".getBytes("UTF-8"))
+     * 
+ * + * where the sender creates a byte array immediately before calling publish. + *

+ * During reconnect the client will try to buffer messages. The buffer size is set + * in the connect options, see {@link Options.Builder#reconnectBufferSize(long) reconnectBufferSize()} + * with a default value of {@link Options#DEFAULT_RECONNECT_BUF_SIZE 8 * 1024 * 1024} bytes. + * If the buffer is exceeded an IllegalStateException is thrown. Applications should use + * this exception as a signal to wait for reconnect before continuing. + *

+ * @param subject the subject to send the message to + * @param replyTo the subject the receiver should send any response to + * @param body the message body + * @throws IllegalStateException if the reconnect buffer is exceeded + */ + void publish(@NonNull String subject, @Nullable String replyTo, byte @Nullable [] body); + + /** + * Send a request to the specified subject, providing a replyTo subject. The + * message body will not be copied. The expected usage with + * string content is something like: + * + *
+     * nc = Nats.connect()
+     * Headers h = new Headers().put("key", "value");
+     * nc.publish("destination", "reply-to", h, "message".getBytes("UTF-8"))
+     * 
+ * + * where the sender creates a byte array immediately before calling publish. + *

+ * During reconnect the client will try to buffer messages. The buffer size is set + * in the connect options, see {@link Options.Builder#reconnectBufferSize(long) reconnectBufferSize()} + * with a default value of {@link Options#DEFAULT_RECONNECT_BUF_SIZE 8 * 1024 * 1024} bytes. + * If the buffer is exceeded an IllegalStateException is thrown. Applications should use + * this exception as a signal to wait for reconnect before continuing. + *

+ * @param subject the subject to send the message to + * @param replyTo the subject the receiver should send any response to + * @param headers Optional headers to publish with the message. + * @param body the message body + * @throws IllegalStateException if the reconnect buffer is exceeded + */ + void publish(@NonNull String subject, @Nullable String replyTo, @Nullable Headers headers, byte @Nullable [] body); + + /** + * Send a message to the specified subject. The message body will + * not be copied. The expected usage with string content is something + * like: + * + *
+     * nc = Nats.connect()
+     * nc.publish(NatsMessage.builder()...build())
+     * 
+ * + * where the sender creates a byte array immediately before calling publish. + * See {@link #publish(String, String, byte[]) publish()} for more details on + * publish during reconnect. + * + * @param message the message + * @throws IllegalStateException if the reconnect buffer is exceeded + */ + void publish(@NonNull Message message); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + * @param subject the subject for the service that will handle the request + * @param body the content of the message + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture request(@NonNull String subject, byte @Nullable [] body); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + * @param subject the subject for the service that will handle the request + * @param headers Optional headers to publish with the message. + * @param body the content of the message + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture request(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + * @param subject the subject for the service that will handle the request + * @param body the content of the message + * @param timeout the time to wait for a response. If not supplied a default will be used. + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture requestWithTimeout(@NonNull String subject, byte @Nullable [] body, @Nullable Duration timeout); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + * @param subject the subject for the service that will handle the request + * @param body the content of the message + * @param headers Optional headers to publish with the message. + * @param timeout the time to wait for a response + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture requestWithTimeout(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body, Duration timeout); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + *

The Message object allows you to set a replyTo, but in requests, + * the replyTo is reserved for internal use as the address for the + * server to respond to the client with the consumer's reply.

+ * + * @param message the message + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture request(@NonNull Message message); + + /** + * Send a request. The returned future will be completed when the + * response comes back. + * + *

The Message object allows you to set a replyTo, but in requests, + * the replyTo is reserved for internal use as the address for the + * server to respond to the client with the consumer's reply.

+ * + * @param message the message + * @param timeout the time to wait for a response + * @return a Future for the response, which may be cancelled on error or timed out + */ + @NonNull + CompletableFuture requestWithTimeout(@NonNull Message message, @Nullable Duration timeout); + + /** + * Send a request and returns the reply or null. This version of request is equivalent + * to calling get on the future returned from {@link #request(String, byte[]) request()} with + * the timeout and handling the ExecutionException and TimeoutException. + * + * @param subject the subject for the service that will handle the request + * @param body the content of the message + * @param timeout the time to wait for a response + * @return the reply message or null if the timeout is reached + * @throws InterruptedException if one is thrown while waiting, in order to propagate it up + */ + @Nullable + Message request(@NonNull String subject, byte @Nullable [] body, @Nullable Duration timeout) throws InterruptedException; + + /** + * Send a request and returns the reply or null. This version of request is equivalent + * to calling get on the future returned from {@link #request(String, byte[]) request()} with + * the timeout and handling the ExecutionException and TimeoutException. + * + * @param subject the subject for the service that will handle the request + * @param headers Optional headers to publish with the message. + * @param body the content of the message + * @param timeout the time to wait for a response + * @return the reply message or null if the timeout is reached + * @throws InterruptedException if one is thrown while waiting, in order to propagate it up + */ + @Nullable + Message request(@NonNull String subject, @Nullable Headers headers, byte @Nullable [] body, @Nullable Duration timeout) throws InterruptedException; + + /** + * Send a request and returns the reply or null. This version of request is equivalent + * to calling get on the future returned from {@link #request(String, byte[]) request()} with + * the timeout and handling the ExecutionException and TimeoutException. + * + *

The Message object allows you to set a replyTo, but in requests, + * the replyTo is reserved for internal use as the address for the + * server to respond to the client with the consumer's reply.

+ * + * @param message the message + * @param timeout the time to wait for a response + * @return the reply message or null if the timeout is reached + * @throws InterruptedException if one is thrown while waiting, in order to propagate it up + */ + @Nullable + Message request(@NonNull Message message, @Nullable Duration timeout) throws InterruptedException; + + /** + * Create a synchronous subscription to the specified subject. + * + *

Use the {@link io.nats.client.Subscription#nextMessage(Duration) nextMessage} + * method to read messages for this subscription. + * + *

See {@link #createDispatcher(MessageHandler) createDispatcher} for + * information about creating an asynchronous subscription with callbacks. + * + *

As of 2.6.1 this method will throw an IllegalArgumentException if the subject contains whitespace. + * + * @param subject the subject to subscribe to + * @return an object representing the subscription + */ + @NonNull + Subscription subscribe(@NonNull String subject); + + /** + * Create a synchronous subscription to the specified subject and queue. + * + *

Use the {@link Subscription#nextMessage(Duration) nextMessage} method to read + * messages for this subscription. + * + *

See {@link #createDispatcher(MessageHandler) createDispatcher} for + * information about creating an asynchronous subscription with callbacks. + * + *

As of 2.6.1 this method will throw an IllegalArgumentException if either string contains whitespace. + * + * @param subject the subject to subscribe to + * @param queueName the queue group to join + * @return an object representing the subscription + */ + @NonNull + Subscription subscribe(@NonNull String subject, @NonNull String queueName); + + /** + * Create a {@code Dispatcher} for this connection. The dispatcher can group one + * or more subscriptions into a single callback thread. All messages go to the + * same {@code MessageHandler}. + * + *

Use the Dispatcher's {@link Dispatcher#subscribe(String)} and + * {@link Dispatcher#subscribe(String, String)} methods to add subscriptions. + * + *

+     * nc = Nats.connect()
+     * d = nc.createDispatcher((m) -> System.out.println(m)).subscribe("hello");
+     * 
+ * + * @param handler The target for the messages. If the handler is null, subscribing without + * using its API that accepts a handler will discard messages. + * @return a new Dispatcher + */ + @NonNull + Dispatcher createDispatcher(@Nullable MessageHandler handler); + + /** + * Convenience method to create a dispatcher with no default handler. Only used + * with JetStream push subscriptions that require specific handlers per subscription. + * + * @return a new Dispatcher + */ + @NonNull + Dispatcher createDispatcher(); + + /** + * Close a dispatcher. This will unsubscribe any subscriptions and stop the delivery thread. + * + *

Once closed the dispatcher will throw an exception on subsequent subscribe or unsubscribe calls. + * + * @param dispatcher the dispatcher to close + */ + void closeDispatcher(@NonNull Dispatcher dispatcher); + + /** + * Attach another ConnectionListener. + * + *

The ConnectionListener will only receive Connection events arriving after it has been attached. When + * a Connection event is raised, the invocation order and parallelism of multiple ConnectionListeners is not + * specified. + * + * @param connectionListener the ConnectionListener to attach. A null listener is a no-op + */ + void addConnectionListener(@NonNull ConnectionListener connectionListener); + + /** + * Detach a ConnectionListioner. This will cease delivery of any further Connection events to this instance. + * + * @param connectionListener the ConnectionListener to detach + */ + void removeConnectionListener(@NonNull ConnectionListener connectionListener); + + /** + * Flush the connection's buffer of outgoing messages, including sending a + * protocol message to and from the server. Passing null is equivalent to + * passing 0, which will wait forever. + * If called while the connection is closed, this method will immediately + * throw a TimeoutException, regardless of the timeout. + * If called while the connection is disconnected due to network issues this + * method will wait for up to the timeout for a reconnect or close. + * + * @param timeout The time to wait for the flush to succeed, pass 0 or null to wait forever. + * @throws TimeoutException if the timeout is exceeded + * @throws InterruptedException if the underlying thread is interrupted + */ + void flush(@Nullable Duration timeout) throws TimeoutException, InterruptedException; + + /** + * Drain tells the connection to process in flight messages before closing. + * Drain initially drains all the consumers, stopping incoming messages. + * Next, publishing is halted and a flush call is used to insure all published + * messages have reached the server. + * Finally, the connection is closed. + * In order to drain subscribers, an unsub protocol message is sent to the server followed by a flush. + * These two steps occur before drain returns. The remaining steps occur in a background thread. + * This method tries to manage the timeout properly, so that if the timeout is 1 second, and the flush + * takes 100ms, the remaining steps have 900ms in the background thread. + * The connection will try to let all messages be drained, but when the timeout is reached + * the connection is closed and any outstanding dispatcher threads are interrupted. + * A future allows this call to be treated as synchronous or asynchronous as + * needed by the application. The value of the future will be true if all the subscriptions + * were drained in the timeout, and false otherwise. The future completes after the connection + * is closed, so any connection handler notifications will happen before the future completes. + * + * @param timeout The time to wait for the drain to succeed, pass 0 or null to wait + * forever. Drain involves moving messages to and from the server + * so a very short timeout is not recommended. If the timeout is reached before + * the drain completes, the connection is simply closed, which can result in message + * loss. + * @return A future that can be used to check if the drain has completed + * @throws InterruptedException if the thread is interrupted + * @throws TimeoutException if the initial flush times out + */ + @NonNull + CompletableFuture drain(@Nullable Duration timeout) throws TimeoutException, InterruptedException; + + /** + * Close the connection and release all blocking calls like {@link #flush flush} + * and {@link Subscription#nextMessage(Duration) nextMessage}. + * If close() is called after {@link #drain(Duration) drain} it will wait up to the connection timeout + * to return, but it will not initiate a close. The drain takes precedence and will initiate the close. + * + * @throws InterruptedException if the thread, or one owned by the connection is interrupted during the close + */ + void close() throws InterruptedException ; + + /** + * Returns the connections current status. + * + * @return the connection's status + */ + @NonNull + Status getStatus(); + + /** + * MaxPayload returns the size limit that a message payload can have. This is + * set by the server configuration and delivered to the client upon connect. + * + * @return the maximum size of a message payload + */ + long getMaxPayload(); + + /** + * Return the list of known server urls, including additional servers discovered + * after a connection has been established. + * Will be empty (but not null) before a connection is made and will represent the last connected server while disconnected + * @return this connection's list of known server URLs + */ + @NonNull + Collection getServers(); + + /** + * a wrapper for useful statistics about the connection + * @return the Statistics implementation + */ + @NonNull + Statistics getStatistics(); + + /** + * the read-only options used to create this connection + * @return the Options + */ + @NonNull + Options getOptions(); + + /** + * Return the server info object. Will never be null, but will be an instance of {@link ServerInfo#EMPTY_INFO} + * before a connection is made, and will represent the last connected server once connected and while disconnected + * until a new connection is made. + * @return the server information such as id, client info, etc. + */ + @NonNull + ServerInfo getServerInfo(); + + /** + * the url used for the current connection, or null if disconnected + * @return the url string + */ + @Nullable + String getConnectedUrl(); + + /** + * the InetAddress of client as known by the NATS server, otherwise null. + * @return the InetAddress + */ + @Nullable + InetAddress getClientInetAddress(); + + /** + * the error text from the last error sent by the server to this client + * @return the last error text + */ + @Nullable + String getLastError(); + + /** + * Clear the last error from the server + */ + void clearLastError(); + + /** + * Create a new inbox subject, can be used for directed replies from + * subscribers. These are guaranteed to be unique, but can be shared and subscribed + * to by others. + * @return the inbox + */ + @NonNull + String createInbox(); + + /** + * Immediately flushes the underlying connection buffer if the connection is valid. + * @throws IOException if the connection flush fails + */ + void flushBuffer() throws IOException; + + /** + * Forces reconnect behavior. Stops the current connection including the reading and writing, + * copies already queued outgoing messages, and then begins the reconnect logic. + * Does not flush. Does not force close the connection. See {@link ForceReconnectOptions}. + * @throws IOException the forceReconnect fails + * @throws InterruptedException the connection is not connected + */ + void forceReconnect() throws IOException, InterruptedException; + + /** + * Forces reconnect behavior. Stops the current connection including the reading and writing, + * copies already queued outgoing messages, and then begins the reconnect logic. + * If options are not provided, the default options are used meaning Does not flush and Does not force close the connection. + * See {@link ForceReconnectOptions}. + * @param options options for how the forceReconnect works. + * @throws IOException the forceReconnect fails + * @throws InterruptedException the connection is not connected + */ + void forceReconnect(@Nullable ForceReconnectOptions options) throws IOException, InterruptedException; + + /** + * Calculates the round trip time between this client and the server. + * @return the RTT as a duration + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + Duration RTT() throws IOException; + + /** + * Get a stream context for a specific stream. + * + *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} + * @param streamName the stream for the context + * @return a StreamContext instance. + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + * @throws JetStreamApiException the request had an error related to the data + */ + @NonNull + StreamContext getStreamContext(@NonNull String streamName) throws IOException, JetStreamApiException; + + /** + * Get a stream context for a specific stream + *

Recommended: {@link StreamContext StreamContext} and {@link ConsumerContext ConsumerContext} are the preferred way to interact with existing streams and consume from streams. + * {@link JetStreamManagement JetStreamManagement} should be used to create streams and consumers. {@link ConsumerContext#consume ConsumerContext.consume()} supports both push and pull consumers transparently. + * + *

+     * nc = Nats.connect();
+	 * StreamContext streamContext = nc.getStreamContext("my-stream");
+	 * ConsumerContext consumerContext = streamContext.getConsumerContext("my-consumer");
+	 * // Or directly: 
+	 * // ConsumerContext consumerContext = nc.getConsumerContext("my-stream", "my-consumer"); 
+	 * consumerContext.consume(
+	 *      	msg -> {
+	 *             System.out.println("   Received " + msg.getSubject());
+	 *             msg.ack();
+	 *           });
+	   
+ * + * @param streamName the stream for the context + * @param options JetStream options. If null, default / no options are used. + * @return a StreamContext instance. + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + * @throws JetStreamApiException the request had an error related to the data + */ + @NonNull + StreamContext getStreamContext(@NonNull String streamName, @Nullable JetStreamOptions options) throws IOException, JetStreamApiException; + + /** + * Get a consumer context for a specific named stream and specific named consumer. + * Verifies that the stream and consumer exist. + * + *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} + * + * @param streamName the name of the stream + * @param consumerName the name of the consumer + * @return a ConsumerContext object + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + * @throws JetStreamApiException the request had an error related to the data + */ + @NonNull + ConsumerContext getConsumerContext(@NonNull String streamName, @NonNull String consumerName) throws IOException, JetStreamApiException; + + /** + * Get a consumer context for a specific named stream and specific named consumer. + * Verifies that the stream and consumer exist. + * + *

Recommended: See {@link #getStreamContext(String, JetStreamOptions) getStreamContext(String, JetStreamOptions)} + * + * @param streamName the name of the stream + * @param consumerName the name of the consumer + * @param options JetStream options. If null, default / no options are used. + * @return a ConsumerContext object + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + * @throws JetStreamApiException the request had an error related to the data + */ + @NonNull + ConsumerContext getConsumerContext(@NonNull String streamName, @NonNull String consumerName, @Nullable JetStreamOptions options) throws IOException, JetStreamApiException; + + /** + * Gets a context for publishing and subscribing to subjects backed by Jetstream streams + * and consumers. + * @return a JetStream instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + JetStream jetStream() throws IOException; + + /** + * Gets a context for publishing and subscribing to subjects backed by Jetstream streams + * and consumers. + * @param options JetStream options. If null, default / no options are used. + * @return a JetStream instance. + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + */ + @NonNull + JetStream jetStream(@Nullable JetStreamOptions options) throws IOException; + + /** + * Gets a context for managing Jetstream streams + * and consumers. + * @return a JetStreamManagement instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + JetStreamManagement jetStreamManagement() throws IOException; + + /** + * Gets a context for managing Jetstream streams + * and consumers. + * @param options JetStream options. If null, default / no options are used. + * @return a JetStreamManagement instance. + * @throws IOException covers various communication issues with the NATS + * server such as timeout or interruption + */ + @NonNull + JetStreamManagement jetStreamManagement(@Nullable JetStreamOptions options) throws IOException; + + /** + * Gets a context for working with a Key Value bucket + * @param bucketName the bucket name + * @return a KeyValue instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + KeyValue keyValue(@NonNull String bucketName) throws IOException; + + /** + * Gets a context for working with a Key Value bucket + * @param bucketName the bucket name + * @param options KeyValue options. If null, default / no options are used. + * @return a KeyValue instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + KeyValue keyValue(@NonNull String bucketName, @Nullable KeyValueOptions options) throws IOException; + + /** + * Gets a context for managing Key Value buckets + * @return a KeyValueManagement instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + KeyValueManagement keyValueManagement() throws IOException; + + /** + * Gets a context for managing Key Value buckets + * @param options KeyValue options. If null, default / no options are used. + * @return a KeyValueManagement instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + KeyValueManagement keyValueManagement(@Nullable KeyValueOptions options) throws IOException; + + /** + * Gets a context for working with an Object Store. + * @param bucketName the bucket name + * @return an ObjectStore instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + ObjectStore objectStore(@NonNull String bucketName) throws IOException; + + /** + * Gets a context for working with an Object Store. + * @param bucketName the bucket name + * @param options ObjectStore options. If null, default / no options are used. + * @return an ObjectStore instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + ObjectStore objectStore(@NonNull String bucketName, @Nullable ObjectStoreOptions options) throws IOException; + + /** + * Gets a context for managing Object Stores + * @return an ObjectStoreManagement instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + ObjectStoreManagement objectStoreManagement() throws IOException; + + /** + * Gets a context for managing Object Stores + * @param options ObjectStore options. If null, default / no options are used. + * @return a ObjectStoreManagement instance. + * @throws IOException various IO exception such as timeout or interruption + */ + @NonNull + ObjectStoreManagement objectStoreManagement(ObjectStoreOptions options) throws IOException; + + /** + * Get the number of messages in the outgoing queue for this connection. + * This value is volatile in the sense that it changes often and may be adjusted by more than one message. + * It changes every time a message is published (put in the outgoing queue) + * and every time a message is removed from the queue to be written over the socket + * @return the number of messages in the outgoing queue + */ + long outgoingPendingMessageCount(); + + /** + * Get the number of bytes based to be written calculated from the messages in the outgoing queue for this connection. + * This value is volatile in the sense that it changes often and may be adjusted by more than one message's bytes. + * It changes every time a message is published (put in the outgoing queue) + * and every time a message is removed from the queue to be written over the socket + * @return the number of messages in the outgoing queue + */ + long outgoingPendingBytes(); +} diff --git a/src/main/java/io/nats/client/ConnectionListener.java b/src/main/java/io/nats/client/ConnectionListener.java index e7a419c68..32d485a17 100644 --- a/src/main/java/io/nats/client/ConnectionListener.java +++ b/src/main/java/io/nats/client/ConnectionListener.java @@ -1,96 +1,116 @@ -// Copyright 2015-2018 The NATS Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package io.nats.client; - -/** - * Applications can use a ConnectionListener to track the status of a {@link Connection Connection}. The - * listener is configured in the {@link Options Options} at creation time. - */ -public interface ConnectionListener { - enum Events { - /** The connection has successfully completed the handshake with the nats-server. */ - CONNECTED(true, "opened"), - /** The connection is permanently closed, either by manual action or failed reconnects. */ - CLOSED(true, "closed"), - /** The connection lost its connection, but may try to reconnect if configured to. */ - DISCONNECTED(true, "disconnected"), - /** The connection was connected, lost its connection and successfully reconnected. */ - RECONNECTED(true, "reconnected"), - /** The connection was reconnected and the server has been notified of all subscriptions. */ - RESUBSCRIBED(false, "subscriptions re-established"), - /** The connection was made aware of new servers from the current server connection. */ - DISCOVERED_SERVERS(false, "discovered servers"), - /** Server Sent a lame duck mode. */ - LAME_DUCK(false, "lame duck mode"); - - private final boolean connectionEvent; - private final String event; - private final String natsEvent; - - Events(boolean connectionEvent, String event) { - this.connectionEvent = connectionEvent; - this.event = event; - if (connectionEvent) { - this.natsEvent = "nats: connection " + event; - } - else { - this.natsEvent = "nats: " + event; - } - } - - public boolean isConnectionEvent() { - return connectionEvent; - } - - public String getEvent() { - return event; - } - - public String getNatsEvent() { - return natsEvent; - } - - /** - * @return the string value for this event - */ - public String toString() { - return this.natsEvent; - } - } - - /** - * @deprecated use new api that gives additional details - * Connection related events that occur asynchronously in the client code are - * sent to a ConnectionListener via a single method. The ConnectionListener can - * use the event type to decide what to do about the problem. - * - * @param conn the connection associated with the error - * @param type the type of event that has occurred - */ - @Deprecated - void connectionEvent(Connection conn, Events type); - - /** - * Connection related events that occur asynchronously in the client code are - * sent to a ConnectionListener via a single method. The ConnectionListener can - * use the event type to decide what to do about the problem. - * @param conn the connection associated with the error - * @param type the type of event that has occurred - * @param time the time of the event, milliseconds since 1/1/1970 - * @param uriDetails extra details about the uri related to this connection event - */ - default void connectionEvent(Connection conn, Events type, Long time, String uriDetails) { - connectionEvent(conn, type); - } -} +// Copyright 2015-2018 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io.nats.client; + +/** + * Applications can use a ConnectionListener to track the status of a {@link Connection Connection}. The + * listener is configured in the {@link Options Options} at creation time. + */ +public interface ConnectionListener { + /** + * Enum for connection events + */ + enum Events { + /** The connection has successfully completed the handshake with the nats-server. */ + CONNECTED(true, "opened"), + /** The connection is permanently closed, either by manual action or failed reconnects. */ + CLOSED(true, "closed"), + /** The connection lost its connection, but may try to reconnect if configured to. */ + DISCONNECTED(true, "disconnected"), + /** The connection was connected, lost its connection and successfully reconnected. */ + RECONNECTED(true, "reconnected"), + /** The connection was reconnected and the server has been notified of all subscriptions. */ + RESUBSCRIBED(false, "subscriptions re-established"), + /** The connection was made aware of new servers from the current server connection. */ + DISCOVERED_SERVERS(false, "discovered servers"), + /** Server Sent a lame duck mode. */ + LAME_DUCK(false, "lame duck mode"); + + private final boolean connectionEvent; + private final String event; + private final String natsEvent; + + /** + * Construct an events enum + * @param connectionEvent whether this is a connection event + * @param event the simple event text + */ + Events(boolean connectionEvent, String event) { + this.connectionEvent = connectionEvent; + this.event = event; + if (connectionEvent) { + this.natsEvent = "nats: connection " + event; + } + else { + this.natsEvent = "nats: " + event; + } + } + + /** + * Whether this event is a connection event. + * @return the flag + */ + public boolean isConnectionEvent() { + return connectionEvent; + } + + /** + * Get the simple event text + * @return the text + */ + public String getEvent() { + return event; + } + + /** + * Get the event text calculated with if it's a connection event and prefixed with "nats:" + * @return the text + */ + public String getNatsEvent() { + return natsEvent; + } + + /** + * @return the string value for this event + */ + public String toString() { + return this.natsEvent; + } + } + + /** + * @deprecated use new api that gives additional details + * Connection related events that occur asynchronously in the client code are + * sent to a ConnectionListener via a single method. The ConnectionListener can + * use the event type to decide what to do about the problem. + * + * @param conn the connection associated with the error + * @param type the type of event that has occurred + */ + @Deprecated + void connectionEvent(Connection conn, Events type); + + /** + * Connection related events that occur asynchronously in the client code are + * sent to a ConnectionListener via a single method. The ConnectionListener can + * use the event type to decide what to do about the problem. + * @param conn the connection associated with the error + * @param type the type of event that has occurred + * @param time the time of the event, milliseconds since 1/1/1970 + * @param uriDetails extra details about the uri related to this connection event + */ + default void connectionEvent(Connection conn, Events type, Long time, String uriDetails) { + connectionEvent(conn, type); + } +} diff --git a/src/main/java/io/nats/client/ConsumeOptions.java b/src/main/java/io/nats/client/ConsumeOptions.java index c5c65082d..1f77f04d9 100644 --- a/src/main/java/io/nats/client/ConsumeOptions.java +++ b/src/main/java/io/nats/client/ConsumeOptions.java @@ -17,6 +17,9 @@ * Consume Options are provided to customize the consume operation. */ public class ConsumeOptions extends BaseConsumeOptions { + /** + * An instance of ConsumeOptions representing the default consume options + */ public static final ConsumeOptions DEFAULT_CONSUME_OPTIONS = ConsumeOptions.builder().build(); private ConsumeOptions(Builder b) { @@ -30,6 +33,7 @@ private ConsumeOptions(Builder b) { public int getBatchSize() { return messages; } + /** * The initial batch size in bytes. * @return the initial batch size in bytes @@ -38,12 +42,22 @@ public long getBatchBytes() { return bytes; } + /** + * Get an instance of the Builder + * @return a builder + */ public static Builder builder() { return new Builder(); } - public static class Builder - extends BaseConsumeOptions.Builder { + /** + * The Consume Options Builder + */ + public static class Builder extends BaseConsumeOptions.Builder { + /** + * Construct a Consume Options Builder + */ + public Builder() {} protected Builder getThis() { return this; } diff --git a/src/main/java/io/nats/client/Consumer.java b/src/main/java/io/nats/client/Consumer.java index 0fdafa3b5..a10414c55 100644 --- a/src/main/java/io/nats/client/Consumer.java +++ b/src/main/java/io/nats/client/Consumer.java @@ -35,12 +35,12 @@ public interface Consumer { /** * The default number of messages a consumer will hold before it starts to drop them. */ - public static final long DEFAULT_MAX_MESSAGES = 512 * 1024; + long DEFAULT_MAX_MESSAGES = 512 * 1024; /** * The default number of bytes a consumer will hold before it starts to drop messages. */ - public static final long DEFAULT_MAX_BYTES = 64 * 1024 * 1024; + long DEFAULT_MAX_BYTES = 64 * 1024 * 1024; /** * Set limits on the maximum number of messages, or maximum size of messages this consumer @@ -57,48 +57,55 @@ public interface Consumer { * @param maxMessages the maximum message count to hold, defaults to {@value #DEFAULT_MAX_MESSAGES} * @param maxBytes the maximum bytes to hold, defaults to {@value #DEFAULT_MAX_BYTES} */ - public void setPendingLimits(long maxMessages, long maxBytes); + void setPendingLimits(long maxMessages, long maxBytes); /** - * @return the pending message limit set by {@link #setPendingLimits(long, long) setPendingLimits} + * the pending message limit set by {@link #setPendingLimits(long, long) setPendingLimits} + * @return the pending message limit */ - public long getPendingMessageLimit(); + long getPendingMessageLimit(); /** - * @return the pending byte limit set by {@link #setPendingLimits(long, long) setPendingLimits} + * the pending byte limit set by {@link #setPendingLimits(long, long) setPendingLimits} + * @return the pending byte limit */ - public long getPendingByteLimit(); + long getPendingByteLimit(); /** - * @return the number of messages waiting to be delivered/popped, {@link #setPendingLimits(long, long) setPendingLimits} + * the number of messages waiting to be delivered/popped, {@link #setPendingLimits(long, long) setPendingLimits} + * @return the pending messages */ - public long getPendingMessageCount(); + long getPendingMessageCount(); /** - * @return the cumulative size of the messages waiting to be delivered/popped, {@link #setPendingLimits(long, long) setPendingLimits} + * the cumulative size of the messages waiting to be delivered/popped, {@link #setPendingLimits(long, long) setPendingLimits} + * @return the number of bytes */ - public long getPendingByteCount(); + long getPendingByteCount(); /** - * @return the total number of messages delivered to this consumer, for all time + * the total number of messages delivered to this consumer, for all time + * @return the delivered count */ - public long getDeliveredCount(); + long getDeliveredCount(); /** - * @return the number of messages dropped from this consumer, since the last call to {@link #clearDroppedCount() clearDroppedCount}. + * the number of messages dropped from this consumer, since the last call to {@link #clearDroppedCount() clearDroppedCount}. + * @return the number of messages */ - public long getDroppedCount(); + long getDroppedCount(); /** * Reset the drop count to 0. */ - public void clearDroppedCount(); + void clearDroppedCount(); /** - * @return whether this consumer is still processing messages. + * whether this consumer is still processing messages. * For a subscription the answer is false after unsubscribe. For a dispatcher, false after stop. + * @return the active state */ - public boolean isActive(); + boolean isActive(); /** * Drain tells the consumer to process in flight, or cached messages, but stop receiving new ones. The library will @@ -114,5 +121,5 @@ public interface Consumer { * @return A future that can be used to check if the drain has completed * @throws InterruptedException if the thread is interrupted */ - public CompletableFuture drain(Duration timeout) throws InterruptedException; + CompletableFuture drain(Duration timeout) throws InterruptedException; } \ No newline at end of file diff --git a/src/main/java/io/nats/client/ErrorListener.java b/src/main/java/io/nats/client/ErrorListener.java index 6d0d8a8d3..9974af54d 100644 --- a/src/main/java/io/nats/client/ErrorListener.java +++ b/src/main/java/io/nats/client/ErrorListener.java @@ -1,173 +1,186 @@ -// Copyright 2015-2018 The NATS Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at: -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package io.nats.client; - -import io.nats.client.support.Status; - -/** - * This library groups problems into four categories: - *

- *
Errors
- *
The server sent an error message using the {@code -err} protocol operation.
- *
Exceptions
- *
A Java exception occurred, and was handled by the library.
- *
Slow Consumers
- *
One of the connections consumers, Subscription or Dispatcher, is slow, and starting to drop messages.
- *
Fast Producers
- *
One of the connections producers is too fast, and is discarding messages
- *
- *

All of these problems are reported to the application code using the ErrorListener. The - * listener is configured in the {@link Options Options} at creation time. - */ -public interface ErrorListener { - /** - * NATs related errors that occur asynchronously in the client library are sent - * to an ErrorListener via errorOccurred. The ErrorListener can use the error text to decide what to do about the problem. - *

The text for an error is described in the protocol doc at `https://nats.io/documentation/internals/nats-protocol`. - *

In some cases the server will close the clients connection after sending one of these errors. In that case, the - * connections {@link ConnectionListener ConnectionListener} will be notified. - * @param conn The connection associated with the error - * @param error The text of error that has occurred, directly from the server - */ - default void errorOccurred(Connection conn, String error) {}; - - /** - * Exceptions that occur in the "normal" course of operations are sent to the - * ErrorListener using exceptionOccurred. Examples include, application exceptions - * during Dispatcher callbacks, IOExceptions from the underlying socket, etc.. - * The library will try to handle these, via reconnect or catching them, but they are - * forwarded here in case the application code needs them for debugging purposes. - * - * @param conn The connection associated with the error - * @param exp The exception that has occurred, and was handled by the library - */ - default void exceptionOccurred(Connection conn, Exception exp) {}; - - /** - * Called by the connection when a "slow" consumer is detected. This call is only made once - * until the consumer stops being slow. At which point it will be called again if the consumer starts - * being slow again. - * - *

See {@link Consumer#setPendingLimits(long, long) Consumer.setPendingLimits} - * for information on how to configure when this method is fired. - * - *

Slow consumers will result in dropped messages each consumer provides a method - * for retrieving the count of dropped messages, see {@link Consumer#getDroppedCount() Consumer.getDroppedCount}. - * - * @param conn The connection associated with the error - * @param consumer The consumer that is being marked slow - */ - default void slowConsumerDetected(Connection conn, Consumer consumer) {}; - - /** - * Called by the connection when a message is discarded. - * - * @param conn The connection that discarded the message - * @param msg The message that is discarded - */ - default void messageDiscarded(Connection conn, Message msg) {} - - /** - * Called when subscription heartbeats are missed according to the configured period and threshold. - * The consumer must be configured with an idle heartbeat time. - * - * @param conn The connection that had the issue - * @param sub the JetStreamSubscription that this occurred on - * @param lastStreamSequence the last received stream sequence - * @param lastConsumerSequence the last received consumer sequence - */ - default void heartbeatAlarm(Connection conn, JetStreamSubscription sub, - long lastStreamSequence, long lastConsumerSequence) {} - - /** - * Called when an unhandled status is received in a push subscription. - * @param conn The connection that had the issue - * @param sub the JetStreamSubscription that this occurred on - * @param status the status - */ - default void unhandledStatus(Connection conn, JetStreamSubscription sub, Status status) {} - - /** - * Called when a pull subscription receives a status message that indicates either - * the subscription or pull might be problematic - * - * @param conn The connection that had the issue - * @param sub the JetStreamSubscription that this occurred on - * @param status the status - */ - default void pullStatusWarning(Connection conn, JetStreamSubscription sub, Status status) {} - - /** - * Called when a pull subscription receives a status message that indicates either - * the subscription cannot continue or the pull request cannot be processed. - * - * @param conn The connection that had the issue - * @param sub the JetStreamSubscription that this occurred on - * @param status the status - */ - default void pullStatusError(Connection conn, JetStreamSubscription sub, Status status) {} - - enum FlowControlSource { FLOW_CONTROL, HEARTBEAT } - - /** - * Called by the connection when a flow control is processed. - * - * @param conn The connection that had the issue - * @param sub the JetStreamSubscription that this occurred on - * @param subject the flow control subject that was handled - * @param source enum indicating flow control handling in response to which type of message - */ - default void flowControlProcessed(Connection conn, JetStreamSubscription sub, String subject, FlowControlSource source) {} - - /** - * Called by the connection when a low level socket write timeout occurs. - * - * @param conn The connection that had the issue - */ - default void socketWriteTimeout(Connection conn) {} - - /** - * General message producing function which understands the possible parameters to listener calls. - * @param label the label for the message - * @param conn The connection that had the issue, if provided. - * @param consumer The consumer that is being marked slow, if applicable - * @param sub the JetStreamSubscription that this occurred on, if applicable - * @param pairs custom string pairs. I.E. "foo: ", fooObject, "bar-", barObject will be appended - * to the message like ", foo: <fooValue>, bar-<barValue>". - * @return the message - */ - default String supplyMessage(String label, Connection conn, Consumer consumer, Subscription sub, Object... pairs) { - StringBuilder sb = new StringBuilder(label == null ? "" : label); - if (conn != null) { - sb.append(", Connection: ").append(conn.getServerInfo().getClientId()); - } - if (consumer != null) { - sb.append(", Consumer: ").append(consumer.hashCode()); - } - if (sub != null) { - sb.append(", Subscription: ").append(sub.hashCode()); - if (sub instanceof JetStreamSubscription) { - JetStreamSubscription jssub = (JetStreamSubscription)sub; - sb.append(", Consumer Name: ").append(jssub.getConsumerName()); - } - } - if (pairs != null && pairs.length % 2 == 0) { - for (int x = 0; x < pairs.length; x++) { - sb.append(", ").append(pairs[x]).append(pairs[++x]); - } - } - return sb.toString(); - } - -} +// Copyright 2015-2018 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io.nats.client; + +import io.nats.client.support.Status; + +/** + * This library groups problems into four categories: + *

+ *
Errors
+ *
The server sent an error message using the {@code -err} protocol operation.
+ *
Exceptions
+ *
A Java exception occurred, and was handled by the library.
+ *
Slow Consumers
+ *
One of the connections consumers, Subscription or Dispatcher, is slow, and starting to drop messages.
+ *
Fast Producers
+ *
One of the connections producers is too fast, and is discarding messages
+ *
+ *

All of these problems are reported to the application code using the ErrorListener. The + * listener is configured in the {@link Options Options} at creation time. + */ +public interface ErrorListener { + /** + * NATs related errors that occur asynchronously in the client library are sent + * to an ErrorListener via errorOccurred. The ErrorListener can use the error text to decide what to do about the problem. + *

The text for an error is described in the protocol doc at `https://nats.io/documentation/internals/nats-protocol`. + *

In some cases the server will close the clients connection after sending one of these errors. In that case, the + * connections {@link ConnectionListener ConnectionListener} will be notified. + * @param conn The connection associated with the error + * @param error The text of error that has occurred, directly from the server + */ + default void errorOccurred(Connection conn, String error) {}; + + /** + * Exceptions that occur in the "normal" course of operations are sent to the + * ErrorListener using exceptionOccurred. Examples include, application exceptions + * during Dispatcher callbacks, IOExceptions from the underlying socket, etc.. + * The library will try to handle these, via reconnect or catching them, but they are + * forwarded here in case the application code needs them for debugging purposes. + * + * @param conn The connection associated with the error + * @param exp The exception that has occurred, and was handled by the library + */ + default void exceptionOccurred(Connection conn, Exception exp) {}; + + /** + * Called by the connection when a "slow" consumer is detected. This call is only made once + * until the consumer stops being slow. At which point it will be called again if the consumer starts + * being slow again. + * + *

See {@link Consumer#setPendingLimits(long, long) Consumer.setPendingLimits} + * for information on how to configure when this method is fired. + * + *

Slow consumers will result in dropped messages each consumer provides a method + * for retrieving the count of dropped messages, see {@link Consumer#getDroppedCount() Consumer.getDroppedCount}. + * + * @param conn The connection associated with the error + * @param consumer The consumer that is being marked slow + */ + default void slowConsumerDetected(Connection conn, Consumer consumer) {}; + + /** + * Called by the connection when a message is discarded. + * + * @param conn The connection that discarded the message + * @param msg The message that is discarded + */ + default void messageDiscarded(Connection conn, Message msg) {} + + /** + * Called when subscription heartbeats are missed according to the configured period and threshold. + * The consumer must be configured with an idle heartbeat time. + * + * @param conn The connection that had the issue + * @param sub the JetStreamSubscription that this occurred on + * @param lastStreamSequence the last received stream sequence + * @param lastConsumerSequence the last received consumer sequence + */ + default void heartbeatAlarm(Connection conn, JetStreamSubscription sub, + long lastStreamSequence, long lastConsumerSequence) {} + + /** + * Called when an unhandled status is received in a push subscription. + * @param conn The connection that had the issue + * @param sub the JetStreamSubscription that this occurred on + * @param status the status + */ + default void unhandledStatus(Connection conn, JetStreamSubscription sub, Status status) {} + + /** + * Called when a pull subscription receives a status message that indicates either + * the subscription or pull might be problematic + * + * @param conn The connection that had the issue + * @param sub the JetStreamSubscription that this occurred on + * @param status the status + */ + default void pullStatusWarning(Connection conn, JetStreamSubscription sub, Status status) {} + + /** + * Called when a pull subscription receives a status message that indicates either + * the subscription cannot continue or the pull request cannot be processed. + * + * @param conn The connection that had the issue + * @param sub the JetStreamSubscription that this occurred on + * @param status the status + */ + default void pullStatusError(Connection conn, JetStreamSubscription sub, Status status) {} + + /** + * Enum for the flow control source + */ + enum FlowControlSource { + /** + * a flow control message + */ + FLOW_CONTROL, + + /** + * a heartbeat message + */ + HEARTBEAT + } + + /** + * Called by the connection when a flow control is processed. + * + * @param conn The connection that had the issue + * @param sub the JetStreamSubscription that this occurred on + * @param subject the flow control subject that was handled + * @param source enum indicating flow control handling in response to which type of message + */ + default void flowControlProcessed(Connection conn, JetStreamSubscription sub, String subject, FlowControlSource source) {} + + /** + * Called by the connection when a low level socket write timeout occurs. + * + * @param conn The connection that had the issue + */ + default void socketWriteTimeout(Connection conn) {} + + /** + * General message producing function which understands the possible parameters to listener calls. + * @param label the label for the message + * @param conn The connection that had the issue, if provided. + * @param consumer The consumer that is being marked slow, if applicable + * @param sub the JetStreamSubscription that this occurred on, if applicable + * @param pairs custom string pairs. I.E. "foo: ", fooObject, "bar-", barObject will be appended + * to the message like ", foo: <fooValue>, bar-<barValue>". + * @return the message + */ + default String supplyMessage(String label, Connection conn, Consumer consumer, Subscription sub, Object... pairs) { + StringBuilder sb = new StringBuilder(label == null ? "" : label); + if (conn != null) { + sb.append(", Connection: ").append(conn.getServerInfo().getClientId()); + } + if (consumer != null) { + sb.append(", Consumer: ").append(consumer.hashCode()); + } + if (sub != null) { + sb.append(", Subscription: ").append(sub.hashCode()); + if (sub instanceof JetStreamSubscription) { + JetStreamSubscription jssub = (JetStreamSubscription)sub; + sb.append(", Consumer Name: ").append(jssub.getConsumerName()); + } + } + if (pairs != null && pairs.length % 2 == 0) { + for (int x = 0; x < pairs.length; x++) { + sb.append(", ").append(pairs[x]).append(pairs[++x]); + } + } + return sb.toString(); + } + +} diff --git a/src/main/java/io/nats/client/FeatureOptions.java b/src/main/java/io/nats/client/FeatureOptions.java index 38b085e1b..ac0eb0ecd 100644 --- a/src/main/java/io/nats/client/FeatureOptions.java +++ b/src/main/java/io/nats/client/FeatureOptions.java @@ -37,6 +37,8 @@ public JetStreamOptions getJetStreamOptions() { /** * KeyValueOptions can be created using a Builder. The builder supports chaining and will * create a default set of options if no methods are calls. + * @param The builder type + * @param the resulting option type */ protected static abstract class Builder { diff --git a/src/main/java/io/nats/client/FetchConsumeOptions.java b/src/main/java/io/nats/client/FetchConsumeOptions.java index 80670b91f..3c7c98462 100644 --- a/src/main/java/io/nats/client/FetchConsumeOptions.java +++ b/src/main/java/io/nats/client/FetchConsumeOptions.java @@ -26,6 +26,9 @@ * Fetch Consume Options are provided to customize the fetch operation. */ public class FetchConsumeOptions extends BaseConsumeOptions { + /** + * An instance of FetchConsumeOptions representing the default fetch options + */ public static final FetchConsumeOptions DEFAULT_FETCH_OPTIONS = FetchConsumeOptions.builder().build(); private final boolean noWait; @@ -56,17 +59,33 @@ public long getMaxBytes() { return bytes; } + /** + * If the options specify no wait + * @return the flag + */ public boolean isNoWait() { return noWait; } + /** + * Get an instance of the builder + * @return a builder + */ public static Builder builder() { return new Builder(); } + /** + * The builder for FetchConsumeOptions + */ public static class Builder extends BaseConsumeOptions.Builder { + /** + * Construct a builder for FetchConsumeOptions + */ + public Builder() {} + protected boolean noWait = false; protected Builder getThis() { return this; } diff --git a/src/main/java/io/nats/client/ForceReconnectOptions.java b/src/main/java/io/nats/client/ForceReconnectOptions.java index 432773db2..79ba487c3 100644 --- a/src/main/java/io/nats/client/ForceReconnectOptions.java +++ b/src/main/java/io/nats/client/ForceReconnectOptions.java @@ -21,7 +21,14 @@ */ public class ForceReconnectOptions { + /** + * A default instance of ForceReconnectOptions + */ public static final ForceReconnectOptions DEFAULT_INSTANCE = ForceReconnectOptions.builder().build(); + + /** + * An instance representing the force close option + */ public static final ForceReconnectOptions FORCE_CLOSE_INSTANCE = ForceReconnectOptions.builder().forceClose().build(); private final boolean forceClose; @@ -32,14 +39,26 @@ private ForceReconnectOptions(Builder b) { this.flushWait = b.flushWait; } + /** + * True if these options represent force close + * @return the flag + */ public boolean isForceClose() { return forceClose; } + /** + * True if these options represent to flush + * @return the flag + */ public boolean isFlush() { return flushWait != null; } + /** + * Get the flush wait setting + * @return the duration + */ public Duration getFlushWait() { return flushWait; } @@ -64,15 +83,20 @@ public static class Builder { */ public Builder() {} + /** + * set the force close flag to true + * @return the builder + */ public Builder forceClose() { this.forceClose = true; return this; } /** - * @param flushWait if supplied and at least 1 millisecond, the forceReconnect will try to - * flush before closing for the specified wait time. Flush happens before close - * so not affected by forceClose option + * if supplied and at least 1 millisecond, the forceReconnect will try to + * flush before closing for the specified wait time. Flush happens before close + * so not affected by forceClose option + * @param flushWait the flush wait duraton * @return the builder */ public Builder flush(Duration flushWait) { @@ -81,9 +105,10 @@ public Builder flush(Duration flushWait) { } /** - * @param flushWaitMillis if supplied and at least 1 millisecond, the forceReconnect will try to - * flush before closing for the specified wait time. Flush happens before close - * so not affected by forceClose option + * if supplied and at least 1 millisecond, the forceReconnect will try to + * flush before closing for the specified wait time. Flush happens before close + * so not affected by forceClose option + * @param flushWaitMillis the flush wait millis * @return the builder */ public Builder flush(long flushWaitMillis) { diff --git a/src/main/java/io/nats/client/IterableConsumer.java b/src/main/java/io/nats/client/IterableConsumer.java index ddf087ebc..3f8283834 100644 --- a/src/main/java/io/nats/client/IterableConsumer.java +++ b/src/main/java/io/nats/client/IterableConsumer.java @@ -15,6 +15,9 @@ import java.time.Duration; +/** + * A simplified consumer that does endless consume on the style of an iterator + */ public interface IterableConsumer extends MessageConsumer { /** * Read the next message. Return null if the calls times out. diff --git a/src/main/java/io/nats/client/JetStream.java b/src/main/java/io/nats/client/JetStream.java index b2df953c0..dad04d0ae 100644 --- a/src/main/java/io/nats/client/JetStream.java +++ b/src/main/java/io/nats/client/JetStream.java @@ -13,10 +13,7 @@ package io.nats.client; -import io.nats.client.api.ConsumerConfiguration; import io.nats.client.api.PublishAck; -import io.nats.client.api.StorageType; -import io.nats.client.api.StreamConfiguration; import io.nats.client.impl.Headers; import java.io.IOException; @@ -26,8 +23,6 @@ /** * JetStream context for access to streams and consumers in NATS. * - *

Basic usage

- * *

{@link #publish(String, byte[]) JetStream.Publish} will send a message on the specified subject, waiting for acknowledgement. * A 503 No responders error will be received if no stream is listening on said subject. * @@ -41,8 +36,7 @@ * It can create a named durable consumers though Options, but we prefer to avoid creating durable consumers implictly. * It is recommened to manage consumers explicitly through {@link StreamContext StreamContext} and {@link ConsumerContext ConsumerContext} or {@link JetStreamManagement JetStreamManagement} * - * - *

Recommended usage for creating streams, consumers, publish and listen on a stream

+ * Recommended usage for creating streams, consumers, publish and listen on a stream *
  *  io.nats.client.Connection nc = Nats.connect();
  *
@@ -80,7 +74,7 @@
  *
  *  
* - *

Recommended usage of asynchronous publishing

+ * Recommended usage of asynchronous publishing * * Jetstream messages can be published asynchronously, returning a CompletableFuture. * Note that you need to check the Future eventually otherwise the delivery guarantee is the same a regular {@link Connection#publish(String, byte[]) Connection.Publish} @@ -104,7 +98,7 @@ * } * } * - * //Now we may send anther batch + * // Now we may send another batch * * * diff --git a/src/main/java/io/nats/client/JetStreamApiException.java b/src/main/java/io/nats/client/JetStreamApiException.java index 185c01340..6a7f47220 100644 --- a/src/main/java/io/nats/client/JetStreamApiException.java +++ b/src/main/java/io/nats/client/JetStreamApiException.java @@ -22,19 +22,27 @@ * related to JetStream. */ public class JetStreamApiException extends Exception { + /** + * The error that this exception represents if there is one + */ private final Error error; /** - * @deprecated Prefer to construct with JetStreamApiException(@NonNull Error error) + * @deprecated Prefer to construct with JetStreamApiException(@NonNull Error) * Construct an exception with the response from the server. * @param apiResponse the response from the server. */ @Deprecated public JetStreamApiException(ApiResponse apiResponse) { // deprecated because of getErrorObject() is marked as @Nullable + //noinspection DataFlowIssue this(apiResponse.getErrorObject()); } + /** + * Construct an exception with an Error + * @param error the error + */ public JetStreamApiException(@NonNull Error error) { super(error.toString()); this.error = error; @@ -42,7 +50,6 @@ public JetStreamApiException(@NonNull Error error) { /** * Get the error code from the response - * * @return the code */ public int getErrorCode() { @@ -51,7 +58,6 @@ public int getErrorCode() { /** * Get the error code from the response - * * @return the code */ public int getApiErrorCode() { @@ -60,7 +66,6 @@ public int getApiErrorCode() { /** * Get the description from the response - * * @return the description */ public String getErrorDescription() { diff --git a/src/main/java/io/nats/client/JetStreamOptions.java b/src/main/java/io/nats/client/JetStreamOptions.java index 1291894e0..123476ca3 100644 --- a/src/main/java/io/nats/client/JetStreamOptions.java +++ b/src/main/java/io/nats/client/JetStreamOptions.java @@ -26,9 +26,16 @@ */ public class JetStreamOptions { + /** + * @deprecated + * Not used anymore + */ @Deprecated public static final Duration DEFAULT_TIMEOUT = Options.DEFAULT_CONNECTION_TIMEOUT; + /** + * An instance of default options + */ public static final JetStreamOptions DEFAULT_JS_OPTIONS = new Builder().build(); private final String jsPrefix; @@ -128,8 +135,15 @@ public static class Builder { private boolean publishNoAck; private boolean optOut290ConsumerCreate; + /** + * Construct a builder + */ public Builder() {} + /** + * Construct a builder from an existing JetStreamOptions + * @param jso the options + */ public Builder(JetStreamOptions jso) { if (jso != null) { if (jso.isDefaultPrefix()) { @@ -209,6 +223,11 @@ public JetStreamOptions build() { } } + /** + * Helper function to convert a domain to a prefix + * @param domain the domain + * @return the prefix + */ public static String convertDomainToPrefix(String domain) { String valid = validatePrefixOrDomain(domain, "Domain", false); return valid == null ? null diff --git a/src/main/java/io/nats/client/JetStreamStatusCheckedException.java b/src/main/java/io/nats/client/JetStreamStatusCheckedException.java index 8d5d5f22c..dd5e4bd53 100644 --- a/src/main/java/io/nats/client/JetStreamStatusCheckedException.java +++ b/src/main/java/io/nats/client/JetStreamStatusCheckedException.java @@ -13,8 +13,15 @@ package io.nats.client; +/** + * A checked version of a JetStreamStatusException + */ public class JetStreamStatusCheckedException extends Exception { + /** + * construct a JetStreamStatusCheckedException from a JetStreamStatusException + * @param cause the JetStreamStatusException cause + */ public JetStreamStatusCheckedException(JetStreamStatusException cause) { super(cause); } diff --git a/src/main/java/io/nats/client/JetStreamStatusException.java b/src/main/java/io/nats/client/JetStreamStatusException.java index 94c03460a..03438785d 100644 --- a/src/main/java/io/nats/client/JetStreamStatusException.java +++ b/src/main/java/io/nats/client/JetStreamStatusException.java @@ -19,9 +19,19 @@ * JetStreamStatusException is used to indicate an unknown status message was received. */ public class JetStreamStatusException extends IllegalStateException { + /** + * A description for an exception that does not provide one + */ public static final String DEFAULT_DESCRIPTION = "Unknown or unprocessed status message"; + /** + * The subscription that this exception occured on + */ private final JetStreamSubscription sub; + + /** + * The status object + */ private final Status status; /** diff --git a/src/main/java/io/nats/client/KeyValueOptions.java b/src/main/java/io/nats/client/KeyValueOptions.java index fcd2b6703..f55159a39 100644 --- a/src/main/java/io/nats/client/KeyValueOptions.java +++ b/src/main/java/io/nats/client/KeyValueOptions.java @@ -60,10 +60,17 @@ protected Builder getThis() { return this; } + /** + * Construct an instance of the builder + */ public Builder() { super(); } + /** + * Construct an instance of the builder based on an existing KeyValueOptions + * @param kvo the KeyValueOptions + */ public Builder(KeyValueOptions kvo) { super(kvo); } diff --git a/src/main/java/io/nats/client/Message.java b/src/main/java/io/nats/client/Message.java index 453963848..d51a7a1e0 100644 --- a/src/main/java/io/nats/client/Message.java +++ b/src/main/java/io/nats/client/Message.java @@ -38,70 +38,85 @@ public interface Message { /** - * @return the subject that this message was sent to + * the subject that this message was sent to + * @return the subject */ String getSubject(); /** - * @return the subject the application is expected to send a reply message on + * the subject the application is expected to send a reply message on + * @return the reply to */ String getReplyTo(); /** - * @return true if there are headers + * true if there are headers + * @return the flag */ boolean hasHeaders(); /** - * @return the headers object for the message + * the headers object for the message + * @return the headers */ Headers getHeaders(); /** - * @return true if there is status + * true if there is status + * @return the flag */ boolean isStatusMessage(); /** - * @return the status object message + * the status object message if this is a status message + * @return the status object */ Status getStatus(); /** - * @return the data from the message + * the data from the message + * @return the data */ byte[] getData(); /** - * @return if is utf8Mode + * @deprecated because the mode doesn't matter + * if is utf8Mode + * @return always false */ + @Deprecated boolean isUtf8mode(); /** - * @return the Subscription associated with this message, may be owned by a Dispatcher + * the Subscription associated with this message, may be owned by a Dispatcher + * @return the subscription */ Subscription getSubscription(); /** - * @return the id associated with the subscription, used by the connection when processing an incoming + * the id associated with the subscription, used by the connection when processing an incoming * message from the server + * @return the SID */ String getSID(); /** - * @return the connection which can be used for publishing, will be null if the subscription is null + * the connection which can be used for publishing, will be null if the subscription is null + * @return the connection */ Connection getConnection(); /** * Gets the metadata associated with a JetStream message. - * @return metadata or null if the message is not a JetStream message. + * metadata or null if the message is not a JetStream message. + * @return the metadata */ NatsJetStreamMetaData metaData(); /** * the last ack that was done with this message - * @return the last ack or null + * the last ack or null + * @return the last ack */ AckType lastAck(); diff --git a/src/main/java/io/nats/client/MessageTtl.java b/src/main/java/io/nats/client/MessageTtl.java index e13f62ba2..507021848 100644 --- a/src/main/java/io/nats/client/MessageTtl.java +++ b/src/main/java/io/nats/client/MessageTtl.java @@ -25,6 +25,10 @@ private MessageTtl(String ttlString) { this.ttlString = ttlString; } + /** + * Get the string representation of the message ttl, used as a value + * @return the string + */ public String getTtlString() { return ttlString; } diff --git a/src/main/java/io/nats/client/NKey.java b/src/main/java/io/nats/client/NKey.java index bdc50f0f0..fcb36cec6 100644 --- a/src/main/java/io/nats/client/NKey.java +++ b/src/main/java/io/nats/client/NKey.java @@ -126,6 +126,11 @@ public enum Type { this.prefix = prefix; } + /** + * Get an instance of the type from a prefix + * @param prefix the prefix + * @return the instance or throws IllegalArgumentException if not found + */ public static Type fromPrefix(int prefix) { if (prefix == PREFIX_BYTE_ACCOUNT) { return ACCOUNT; @@ -466,6 +471,7 @@ public static NKey fromSeed(char[] seed) { } /** + * if the public key is an account public key * @param src the encoded public key * @return true if the public key is an account public key */ @@ -474,6 +480,7 @@ public static boolean isValidPublicAccountKey(char[] src) { } /** + * if the public key is a cluster public key * @param src the encoded public key * @return true if the public key is a cluster public key */ @@ -482,6 +489,7 @@ public static boolean isValidPublicClusterKey(char[] src) { } /** + * if the public key is an operator public key * @param src the encoded public key * @return true if the public key is an operator public key */ @@ -490,6 +498,7 @@ public static boolean isValidPublicOperatorKey(char[] src) { } /** + * if the public key is a server public key * @param src the encoded public key * @return true if the public key is a server public key */ @@ -498,6 +507,7 @@ public static boolean isValidPublicServerKey(char[] src) { } /** + * if the public key is a user public key * @param src the encoded public key * @return true if the public key is a user public key */ @@ -541,6 +551,7 @@ public void clear() { } /** + * the string encoded seed for this NKey * @return the string encoded seed for this NKey */ public char[] getSeed() { @@ -558,6 +569,7 @@ public char[] getSeed() { } /** + * the encoded public key for this NKey * @return the encoded public key for this NKey * * @throws GeneralSecurityException if there is an encryption problem @@ -572,6 +584,7 @@ public char[] getPublicKey() throws GeneralSecurityException, IOException { } /** + * the encoded private key for this NKey * @return the encoded private key for this NKey * * @throws GeneralSecurityException if there is an encryption problem @@ -587,8 +600,8 @@ public char[] getPrivateKey() throws GeneralSecurityException, IOException { } /** - * @return A Java security keypair that represents this NKey in Java security - * form. + * A Java security keypair that represents this NKey in Java security form. + * @return A Java security keypair that represents this NKey in Java security form. * * @throws GeneralSecurityException if there is an encryption problem * @throws IOException if there is a problem encoding or decoding @@ -612,6 +625,7 @@ public KeyPair getKeyPair() throws GeneralSecurityException, IOException { } /** + * the Type of this NKey * @return the Type of this NKey */ public Type getType() { diff --git a/src/main/java/io/nats/client/NUID.java b/src/main/java/io/nats/client/NUID.java index b09c2bfbe..0129ff097 100644 --- a/src/main/java/io/nats/client/NUID.java +++ b/src/main/java/io/nats/client/NUID.java @@ -84,6 +84,7 @@ public NUID() { } /** + * the next NUID string from a shared global NUID instance * @return the next NUID string from a shared global NUID instance */ public static String nextGlobal() { @@ -91,6 +92,7 @@ public static String nextGlobal() { } /** + * the next sequence portion of the NUID string from a shared global NUID instance * @return the next sequence portion of the NUID string from a shared global NUID instance */ public static String nextGlobalSequence() { @@ -178,6 +180,7 @@ final void randomizePrefix() { } /** + * The pre portion of the NUID * @return the pre */ char[] getPre() { @@ -186,7 +189,6 @@ char[] getPre() { /** * Return the current sequence value. - * * @return the seq */ long getSeq() { @@ -195,9 +197,7 @@ long getSeq() { /** * Set the sequence to the supplied value. - * - * @param seq - * the seq to set + * @param seq the seq to set */ void setSeq(long seq) { this.seq = seq; diff --git a/src/main/java/io/nats/client/NatsSystemClock.java b/src/main/java/io/nats/client/NatsSystemClock.java index 12661a5e8..b39356376 100644 --- a/src/main/java/io/nats/client/NatsSystemClock.java +++ b/src/main/java/io/nats/client/NatsSystemClock.java @@ -13,6 +13,9 @@ package io.nats.client; +/** + * Bridge to the NatsSystemClockProvider implementation + */ public final class NatsSystemClock { private static NatsSystemClockProvider PROVIDER = new NatsSystemClockProvider() {}; @@ -35,7 +38,7 @@ public static long currentTimeMillis() { } /** - * Get the current nano time from the provider + * Get the current nano time from the provider, suitable for calculating elapsed time * @return the nano time */ public static long nanoTime() { diff --git a/src/main/java/io/nats/client/NatsSystemClockProvider.java b/src/main/java/io/nats/client/NatsSystemClockProvider.java index 447356ccc..6de3646c0 100644 --- a/src/main/java/io/nats/client/NatsSystemClockProvider.java +++ b/src/main/java/io/nats/client/NatsSystemClockProvider.java @@ -13,7 +13,19 @@ package io.nats.client; +/** + * Interface to implement to provide a custom clock implementation + */ public interface NatsSystemClockProvider { + /** + * Returns the current time in milliseconds + * @return the current time in milliseconds + */ default long currentTimeMillis() { return System.currentTimeMillis(); } + + /** + * A nano time suitable for calculating elapsed time + * @return the nano time + */ default long nanoTime() { return System.nanoTime(); } } diff --git a/src/main/java/io/nats/client/ObjectStoreOptions.java b/src/main/java/io/nats/client/ObjectStoreOptions.java index 2093c28c5..261e156f6 100644 --- a/src/main/java/io/nats/client/ObjectStoreOptions.java +++ b/src/main/java/io/nats/client/ObjectStoreOptions.java @@ -60,10 +60,17 @@ protected Builder getThis() { return this; } + /** + * Construct the builder + */ public Builder() { super(); } + /** + * Construct the builder from existing options + * @param oso the options + */ public Builder(ObjectStoreOptions oso) { super(oso); } diff --git a/src/main/java/io/nats/client/Options.java b/src/main/java/io/nats/client/Options.java index 6848308bb..8a4196687 100644 --- a/src/main/java/io/nats/client/Options.java +++ b/src/main/java/io/nats/client/Options.java @@ -1063,6 +1063,10 @@ public Builder noResolveHostnames() { return this; } + /** + * set to report no responders + * @return the Builder for chaining + */ public Builder reportNoResponders() { this.reportNoResponders = true; return this; @@ -1229,7 +1233,7 @@ public Builder sslContextFactory(SSLContextFactory sslContextFactory) { } /** - * + * the path to the keystore file * @param keystore the path to the keystore file * @return the Builder for chaining */ @@ -1239,7 +1243,7 @@ public Builder keystorePath(String keystore) { } /** - * + * the password for the keystore * @param keystorePassword the password for the keystore * @return the Builder for chaining */ @@ -1249,7 +1253,7 @@ public Builder keystorePassword(char[] keystorePassword) { } /** - * + * the path to the trust store file * @param truststore the path to the trust store file * @return the Builder for chaining */ @@ -1259,7 +1263,7 @@ public Builder truststorePath(String truststore) { } /** - * + * The password for the trust store * @param truststorePassword the password for the trust store * @return the Builder for chaining */ @@ -1269,8 +1273,8 @@ public Builder truststorePassword(char[] truststorePassword) { } /** - * - * @param tlsAlgorithm the tls algorithm. Default is {@value SSLUtils#DEFAULT_TLS_ALGORITHM} + * The tls algorithm to use Default is {@value SSLUtils#DEFAULT_TLS_ALGORITHM} + * @param tlsAlgorithm the tls algorithm. * @return the Builder for chaining */ public Builder tlsAlgorithm(String tlsAlgorithm) { @@ -1279,8 +1283,8 @@ public Builder tlsAlgorithm(String tlsAlgorithm) { } /** - * - * @param credentialPath the path to the credentials file for creating an {@link AuthHandler AuthHandler} + * the path to the credentials file for creating an {@link AuthHandler AuthHandler} + * @param credentialPath the path to the credentials file * @return the Builder for chaining */ public Builder credentialPath(String credentialPath) { @@ -2044,6 +2048,10 @@ else if (useDefaultTls) { // ---------------------------------------------------------------------------------------------------- // BUILDER COPY CONSTRUCTOR // ---------------------------------------------------------------------------------------------------- + /** + * Construction an Options.Builder copying an existing Options + * @param o the options + */ public Builder(Options o) { if (o == null) { throw new IllegalArgumentException("Options cannot be null"); @@ -2192,6 +2200,7 @@ private Options(Builder b) { // GETTERS // ---------------------------------------------------------------------------------------------------- /** + * Get the general executor * @return the executor, see {@link Builder#executor(ExecutorService) executor()} in the builder doc */ public ExecutorService getExecutor() { @@ -2207,6 +2216,7 @@ private ExecutorService _getInternalExecutor() { } /** + * Get the ScheduledExecutorService instance * @return the ScheduledExecutorService, see {@link Builder#scheduledExecutor(ScheduledExecutorService) scheduledExecutor()} in the builder doc */ public ScheduledExecutorService getScheduledExecutor() { @@ -2224,16 +2234,25 @@ private ScheduledExecutorService _getInternalScheduledExecutor() { return stpe; } + /** + * whether the general executor is the internal one versus a user supplied one + * @return true if the executor is internal + */ public boolean executorIsInternal() { return this.executor == null; } + /** + * whether the scheduled executor is the internal one versus a user supplied one + * @return true if the executor is internal + */ public boolean scheduledExecutorIsInternal() { return this.scheduledExecutor == null; } /** - * @return the callback executor, see {@link Builder#callbackThreadFactory(ThreadFactory) callbackThreadFactory()} in the builder doc + * the callback executor, see {@link Builder#callbackThreadFactory(ThreadFactory) callbackThreadFactory()} in the builder doc + * @return the executor */ public ExecutorService getCallbackExecutor() { return this.callbackThreadFactory == null ? @@ -2241,7 +2260,8 @@ public ExecutorService getCallbackExecutor() { } /** - * @return the connect executor, see {@link Builder#connectThreadFactory(ThreadFactory) connectThreadFactory()} in the builder doc + * the connect executor, see {@link Builder#connectThreadFactory(ThreadFactory) connectThreadFactory()} in the builder doc + * @return the executor */ public ExecutorService getConnectExecutor() { return this.connectThreadFactory == null ? @@ -2249,7 +2269,8 @@ public ExecutorService getConnectExecutor() { } /** - * @return the list of HttpRequest interceptors. + * the list of HttpRequest interceptors. + * @return the list */ public List> getHttpRequestInterceptors() { return null == this.httpRequestInterceptors @@ -2258,14 +2279,16 @@ public List> getHttpRequestInterceptors } /** - * @return the proxy to used for all sockets. + * the proxy to used for all sockets. + * @return the proxy */ public Proxy getProxy() { return this.proxy; } /** - * @return the error listener. Will be an instance of ErrorListenerLoggerImpl if not user supplied. See {@link Builder#errorListener(ErrorListener) errorListener()} in the builder doc + * the error listener. Will be an instance of ErrorListenerLoggerImpl if not user supplied. See {@link Builder#errorListener(ErrorListener) errorListener()} in the builder doc + * @return the listener */ public ErrorListener getErrorListener() { return this.errorListener; @@ -2282,49 +2305,56 @@ public TimeTraceLogger getTimeTraceLogger() { } /** - * @return the connection listener, or null, see {@link Builder#connectionListener(ConnectionListener) connectionListener()} in the builder doc + * the connection listener, or null, see {@link Builder#connectionListener(ConnectionListener) connectionListener()} in the builder doc + * @return the listener */ public ConnectionListener getConnectionListener() { return this.connectionListener; } /** - * @return the read listener, or null, see {@link Builder#readListener(ReadListener) readListener()} in the builder doc + * the read listener, or null, see {@link Builder#readListener(ReadListener) readListener()} in the builder doc + * @return the listener */ public ReadListener getReadListener() { return this.readListener; } /** - * @return the statistics collector, or null, see {@link Builder#statisticsCollector(StatisticsCollector) statisticsCollector()} in the builder doc + * the statistics collector, or null, see {@link Builder#statisticsCollector(StatisticsCollector) statisticsCollector()} in the builder doc + * @return the collector */ public StatisticsCollector getStatisticsCollector() { return this.statisticsCollector; } /** - * @return the auth handler, or null, see {@link Builder#authHandler(AuthHandler) authHandler()} in the builder doc + * the auth handler, or null, see {@link Builder#authHandler(AuthHandler) authHandler()} in the builder doc + * @return the handler */ public AuthHandler getAuthHandler() { return this.authHandler; } /** - * @return the reconnection delay handler, or null, see {@link Builder#reconnectDelayHandler(ReconnectDelayHandler) reconnectDelayHandler()} in the builder doc + * the reconnection delay handler, or null, see {@link Builder#reconnectDelayHandler(ReconnectDelayHandler) reconnectDelayHandler()} in the builder doc + * @return the handler */ public ReconnectDelayHandler getReconnectDelayHandler() { return this.reconnectDelayHandler; } /** - * @return the dataport type for connections created by this options object, see {@link Builder#dataPortType(String) dataPortType()} in the builder doc + * the DataPort class type for connections created by this options object, see {@link Builder#dataPortType(String) dataPortType()} in the builder doc + * @return the DataPort class type */ public String getDataPortType() { return this.dataPortType; } /** - * @return the data port described by these options + * the data port described by these options + * @return the data port */ public DataPort buildDataPort() { DataPort dp; @@ -2344,7 +2374,8 @@ public DataPort buildDataPort() { } /** - * @return the servers configured in options, see {@link Builder#servers(String[]) servers()} in the builder doc + * the servers as configured in options as URI's, see {@link Builder#servers(String[]) servers()} in the builder doc + * @return the processed servers */ public List getServers() { List list = new ArrayList<>(); @@ -2355,98 +2386,112 @@ public List getServers() { } /** - * @return the servers configured in options, see {@link Builder#servers(String[]) servers()} in the builder doc + * the servers as configured in options as NatsUri's, see {@link Builder#servers(String[]) servers()} in the builder doc + * @return the processed servers */ public List getNatsServerUris() { return natsServerUris; } /** - * @return the servers as given to the options, since the servers are normalized + * the servers as given to the options, since the servers are normalized + * @return the raw servers */ public List getUnprocessedServers() { return unprocessedServers; } /** - * @return should we turn off randomization for server connection attempts, see {@link Builder#noRandomize() noRandomize()} in the builder doc + * should we turn off randomization for server connection attempts, see {@link Builder#noRandomize() noRandomize()} in the builder doc + * @return true if we should turn off randomization */ public boolean isNoRandomize() { return noRandomize; } /** - * @return should we resolve hostnames for server connection attempts, see {@link Builder#noResolveHostnames() noResolveHostnames()} in the builder doc + * should we resolve hostnames for server connection attempts, see {@link Builder#noResolveHostnames() noResolveHostnames()} in the builder doc + * @return true if we should resolve hostnames */ public boolean isNoResolveHostnames() { return noResolveHostnames; } /** - * @return should complete with exception futures for requests that get no responders instead of cancelling the future, see {@link Builder#reportNoResponders() reportNoResponders()} in the builder doc + * should complete with exception futures for requests that get no responders instead of cancelling the future, see {@link Builder#reportNoResponders() reportNoResponders()} in the builder doc + * @return true if we should report no responders instead of cancelling them */ public boolean isReportNoResponders() { return reportNoResponders; } /** - * @return the connectionName, see {@link Builder#connectionName(String) connectionName()} in the builder doc + * the connectionName, see {@link Builder#connectionName(String) connectionName()} in the builder doc + * @return the connectionName */ public String getConnectionName() { return connectionName; } /** - * @return are we in verbose mode, see {@link Builder#verbose() verbose()} in the builder doc + * are we in verbose mode, see {@link Builder#verbose() verbose()} in the builder doc + * @return true if we are in verbose mode */ public boolean isVerbose() { return verbose; } /** - * @return is echo-ing disabled, see {@link Builder#noEcho() noEcho()} in the builder doc + * is echo-ing disabled, see {@link Builder#noEcho() noEcho()} in the builder doc + * @return true if echo-ing is disabled */ public boolean isNoEcho() { return noEcho; } /** - * @return are headers disabled, see {@link Builder#noHeaders() noHeaders()} in the builder doc + * are headers disabled, see {@link Builder#noHeaders() noHeaders()} in the builder doc + * @return true if headers are disabled */ public boolean isNoHeaders() { return noHeaders; } /** - * @return is NoResponders ignored disabled, see {@link Builder#noNoResponders() noNoResponders()} in the builder doc + * is NoResponders ignored disabled, see {@link Builder#noNoResponders() noNoResponders()} in the builder doc + * @return true if no no-responders */ public boolean isNoNoResponders() { return noNoResponders; } /** - * @return clientSideLimitChecks flag + * clientSideLimitChecks + * @return true if the client will perform limit checks */ public boolean clientSideLimitChecks() { return clientSideLimitChecks; } /** - * @return whether utf8 subjects are supported, see {@link Builder#supportUTF8Subjects() supportUTF8Subjects()} in the builder doc. + * whether utf8 subjects are supported, see {@link Builder#supportUTF8Subjects() supportUTF8Subjects()} in the builder doc. + * @return true if utf8 subjects are supported */ public boolean supportUTF8Subjects() { return supportUTF8Subjects; } /** - * @return are we using pedantic protocol, see {@link Builder#pedantic() pedantic()} in the builder doc + * are we using pedantic protocol, see {@link Builder#pedantic() pedantic()} in the builder doc + * @return true if using pedantic protocol */ public boolean isPedantic() { return pedantic; } /** - * @return should we track advanced stats, see {@link Builder#turnOnAdvancedStats() turnOnAdvancedStats()} in the builder doc + * should we track advanced stats, see {@link Builder#turnOnAdvancedStats() turnOnAdvancedStats()} in the builder doc + * @return true is advance stat tracking is on */ public boolean isTrackAdvancedStats() { return trackAdvancedStats; @@ -2461,7 +2506,8 @@ public boolean isTraceConnection() { } /** - * @return the maximum length of a control line, see {@link Builder#maxControlLine(int) maxControlLine()} in the builder doc + * the maximum length of a control line, see {@link Builder#maxControlLine(int) maxControlLine()} in the builder doc + * @return the maximum length */ public int getMaxControlLine() { return maxControlLine; @@ -2469,120 +2515,137 @@ public int getMaxControlLine() { /** * - * @return true if there is an sslContext for these Options, otherwise false, see {@link Builder#secure() secure()} in the builder doc + * is there an sslContext for these Options, otherwise false, see {@link Builder#secure() secure()} in the builder doc + * @return true if there is an sslContext */ public boolean isTLSRequired() { return sslContext != null; } /** - * @return the sslContext, see {@link Builder#secure() secure()} in the builder doc + * the sslContext, see {@link Builder#secure() secure()} in the builder doc + * @return the sslContext */ public SSLContext getSslContext() { return sslContext; } /** - * @return the maxReconnect attempts to make before failing, see {@link Builder#maxReconnects(int) maxReconnects()} in the builder doc + * the maxReconnect attempts to make before failing, see {@link Builder#maxReconnects(int) maxReconnects()} in the builder doc + * @return the maxReconnect attempts */ public int getMaxReconnect() { return maxReconnect; } /** - * @return the reconnectWait, used between reconnect attempts, see {@link Builder#reconnectWait(Duration) reconnectWait()} in the builder doc + * the reconnectWait, used between reconnect attempts, see {@link Builder#reconnectWait(Duration) reconnectWait()} in the builder doc + * @return the reconnectWait */ public Duration getReconnectWait() { return reconnectWait; } /** - * @return the reconnectJitter, used between reconnect attempts to vary the reconnect wait, see {@link Builder#reconnectJitter(Duration) reconnectJitter()} in the builder doc + * the reconnectJitter, used between reconnect attempts to vary the reconnect wait, see {@link Builder#reconnectJitter(Duration) reconnectJitter()} in the builder doc + * @return the reconnectJitter */ public Duration getReconnectJitter() { return reconnectJitter; } /** - * @return the reconnectJitterTls, used between reconnect attempts to vary the reconnect wait whe using tls/secure, see {@link Builder#reconnectJitterTls(Duration) reconnectJitterTls()} in the builder doc + * the reconnectJitterTls, used between reconnect attempts to vary the reconnect wait whe using tls/secure, see {@link Builder#reconnectJitterTls(Duration) reconnectJitterTls()} in the builder doc + * @return the reconnectJitterTls */ public Duration getReconnectJitterTls() { return reconnectJitterTls; } /** - * @return the connectionTimeout, see {@link Builder#connectionTimeout(Duration) connectionTimeout()} in the builder doc + * the connectionTimeout, see {@link Builder#connectionTimeout(Duration) connectionTimeout()} in the builder doc + * @return the connectionTimeout */ public Duration getConnectionTimeout() { return connectionTimeout; } /** - * @return the socketReadTimeoutMillis, see {@link Builder#socketReadTimeoutMillis(int) socketReadTimeoutMillis} in the builder doc + * the socketReadTimeoutMillis, see {@link Builder#socketReadTimeoutMillis(int) socketReadTimeoutMillis} in the builder doc + * @return the socketReadTimeoutMillis */ public int getSocketReadTimeoutMillis() { return socketReadTimeoutMillis; } /** - * @return the socketWriteTimeout, see {@link Builder#socketWriteTimeout(long) socketWriteTimeout} in the builder doc + * the socketWriteTimeout, see {@link Builder#socketWriteTimeout(long) socketWriteTimeout} in the builder doc + * @return the socketWriteTimeout */ public Duration getSocketWriteTimeout() { return socketWriteTimeout; } /** - * @return the socket so linger number of seconds, see {@link Builder#socketSoLinger(int) socketSoLinger()} in the builder doc + * the socket so linger number of seconds, see {@link Builder#socketSoLinger(int) socketSoLinger()} in the builder doc + * @return the socket so linger number of seconds */ public int getSocketSoLinger() { return socketSoLinger; } /** - * @return the number of bytes to set the for the SO_RCVBUF property on the socket + * the number of bytes to set the for the SO_RCVBUF property on the socket + * @return the number of bytes */ public int getReceiveBufferSize() { return receiveBufferSize; } /** - * @return the number of bytes to set the for the SO_SNDBUF property on the socket + * the number of bytes to set the for the SO_SNDBUF property on the socket + * @return the number of bytes */ public int getSendBufferSize() { return sendBufferSize; } /** - * @return the pingInterval, see {@link Builder#pingInterval(Duration) pingInterval()} in the builder doc + * the pingInterval, see {@link Builder#pingInterval(Duration) pingInterval()} in the builder doc + * @return interval */ public Duration getPingInterval() { return pingInterval; } /** - * @return the request cleanup interval, see {@link Builder#requestCleanupInterval(Duration) requestCleanupInterval()} in the builder doc + * the request cleanup interval, see {@link Builder#requestCleanupInterval(Duration) requestCleanupInterval()} in the builder doc + * @return the interval */ public Duration getRequestCleanupInterval() { return requestCleanupInterval; } /** - * @return the maxPingsOut to limit the number of pings on the wire, see {@link Builder#maxPingsOut(int) maxPingsOut()} in the builder doc + * the maxPingsOut to limit the number of pings on the wire, see {@link Builder#maxPingsOut(int) maxPingsOut()} in the builder doc + * @return the max pings out */ public int getMaxPingsOut() { return maxPingsOut; } /** - * @return the reconnectBufferSize, to limit the amount of data held during - * reconnection attempts, see {@link Builder#reconnectBufferSize(long) reconnectBufferSize()} in the builder doc + * the reconnectBufferSize, to limit the amount of data held during + * reconnection attempts, see {@link Builder#reconnectBufferSize(long) reconnectBufferSize()} in the builder doc + * @return the reconnectBufferSize */ public long getReconnectBufferSize() { return reconnectBufferSize; } /** - * @return the default size for buffers in the connection code, see {@link Builder#bufferSize(int) bufferSize()} in the builder doc + * the default size for buffers in the connection code, see {@link Builder#bufferSize(int) bufferSize()} in the builder doc + * @return the default size in bytes */ public int getBufferSize() { return bufferSize; @@ -2598,7 +2661,8 @@ public String getUsername() { } /** - * @return the username to use for basic authentication, see {@link Builder#userInfo(String, String) userInfo()} in the builder doc + * the username to use for basic authentication, see {@link Builder#userInfo(String, String) userInfo()} in the builder doc + * @return the username */ public char[] getUsernameChars() { return username; @@ -2614,7 +2678,8 @@ public String getPassword() { } /** - * @return the password to use for basic authentication, see {@link Builder#userInfo(String, String) userInfo()} in the builder doc + * the password to use for basic authentication, see {@link Builder#userInfo(String, String) userInfo()} in the builder doc + * @return the password */ public char[] getPasswordChars() { return password; @@ -2631,37 +2696,43 @@ public String getToken() { } /** - * @return the token to be used for token-based authentication, see {@link Builder#token(String) token()} in the builder doc + * the token to be used for token-based authentication, see {@link Builder#token(String) token()} in the builder doc + * generated from the token supplier if the user supplied one. + * @return the token */ public char[] getTokenChars() { return tokenSupplier.get(); } /** - * @return the flag to turn on old style requests, see {@link Builder#oldRequestStyle() oldStyleRequest()} in the builder doc + * the flag to turn on old style requests, see {@link Builder#oldRequestStyle() oldStyleRequest()} in the builder doc + * @return the flag */ public boolean isOldRequestStyle() { return useOldRequestStyle; } /** - * @return the inbox prefix to use for requests, see {@link Builder#inboxPrefix(String) inboxPrefix()} in the builder doc + * the inbox prefix to use for requests, see {@link Builder#inboxPrefix(String) inboxPrefix()} in the builder doc + * @return the inbox prefix */ public String getInboxPrefix() { return inboxPrefix; } /** - * @return the maximum number of messages in the outgoing queue, see {@link Builder#maxMessagesInOutgoingQueue(int) + * the maximum number of messages in the outgoing queue, see {@link Builder#maxMessagesInOutgoingQueue(int) * maxMessagesInOutgoingQueue(int)} in the builder doc + * @return the maximum number of messages */ public int getMaxMessagesInOutgoingQueue() { return maxMessagesInOutgoingQueue; } /** - * @return should we discard messages when the outgoing queue is full, see {@link Builder#discardMessagesWhenOutgoingQueueFull() + * should we discard messages when the outgoing queue is full, see {@link Builder#discardMessagesWhenOutgoingQueueFull() * discardMessagesWhenOutgoingQueueFull()} in the builder doc + * @return true if we should discard messages when the outgoing queue is full */ public boolean isDiscardMessagesWhenOutgoingQueueFull() { return discardMessagesWhenOutgoingQueueFull; @@ -2729,6 +2800,12 @@ public boolean isEnableFastFallback() { return enableFastFallback; } + /** + * create a URI from a server uri. + * @param serverURI the text uri + * @return the URI object + * @throws URISyntaxException if the text version is malformed or illegal + */ public URI createURIForServer(String serverURI) throws URISyntaxException { return new NatsUri(serverURI).getUri(); } diff --git a/src/main/java/io/nats/client/PullRequestOptions.java b/src/main/java/io/nats/client/PullRequestOptions.java index f3beb0c1d..e7596b165 100644 --- a/src/main/java/io/nats/client/PullRequestOptions.java +++ b/src/main/java/io/nats/client/PullRequestOptions.java @@ -37,6 +37,10 @@ public class PullRequestOptions implements JsonSerializable { private final long minPending; private final long minAckPending; + /** + * Construct PullRequestOptions from the builder + * @param b the builder + */ public PullRequestOptions(Builder b) { this.batchSize = b.batchSize; this.maxBytes = b.maxBytes; @@ -110,16 +114,32 @@ public Duration getIdleHeartbeat() { return idleHeartbeat; } + /** + * Get the group option + * @return the group + */ public String getGroup() { return group; } + /** + * Get the priority + * @return the priority + */ public int getPriority() { return priority; } + /** + * Get the min pending setting + * @return the min pending + */ public long getMinPending() { return minPending; } + /** + * Get the min ack pending setting + * @return the min ack setting + */ public long getMinAckPending() { return minAckPending; } @@ -142,6 +162,9 @@ public static Builder noWait(int batchSize) { return new Builder().batchSize(batchSize).noWait(); } + /** + * The builder for PullRequestOptions + */ public static class Builder { private int batchSize; private long maxBytes; @@ -153,6 +176,11 @@ public static class Builder { private long minPending = -1; private long minAckPending = -1; + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * Set the batch size for the pull * @param batchSize the size of the batch. Must be greater than 0 diff --git a/src/main/java/io/nats/client/PullSubscribeOptions.java b/src/main/java/io/nats/client/PullSubscribeOptions.java index d791b6982..e3e3ad1f5 100644 --- a/src/main/java/io/nats/client/PullSubscribeOptions.java +++ b/src/main/java/io/nats/client/PullSubscribeOptions.java @@ -18,6 +18,9 @@ * Options are set using the {@link PullSubscribeOptions.Builder} or static helper methods. */ public class PullSubscribeOptions extends SubscribeOptions { + /** + * An instance of PullSubscribeOptions with the default options + */ public static final PullSubscribeOptions DEFAULT_PULL_OPTS = PullSubscribeOptions.builder().build(); private PullSubscribeOptions(Builder builder) { @@ -71,6 +74,10 @@ public static PullSubscribeOptions fastBind(String stream, String name) { */ public static class Builder extends SubscribeOptions.Builder { + /** + * Construct an instance of the builder + */ + public Builder() {} @Override protected Builder getThis() { diff --git a/src/main/java/io/nats/client/PurgeOptions.java b/src/main/java/io/nats/client/PurgeOptions.java index 6c015db1e..0122c5565 100644 --- a/src/main/java/io/nats/client/PurgeOptions.java +++ b/src/main/java/io/nats/client/PurgeOptions.java @@ -88,11 +88,19 @@ public static PurgeOptions subject(String subject) { return new Builder().subject(subject).build(); } + /** + * Builder class for PurgeOptions + */ public static class Builder { private String subject; private long seq = -1; private long keep = -1; + /** + * Construct a builder instance + */ + public Builder() {} + /** * Set the subject to filter the purge. Wildcards allowed. * @param subject the subject diff --git a/src/main/java/io/nats/client/PushSubscribeOptions.java b/src/main/java/io/nats/client/PushSubscribeOptions.java index ad1363eba..fa41a9f0b 100644 --- a/src/main/java/io/nats/client/PushSubscribeOptions.java +++ b/src/main/java/io/nats/client/PushSubscribeOptions.java @@ -20,6 +20,9 @@ * Options are set using the {@link PushSubscribeOptions.Builder} or static helper methods. */ public class PushSubscribeOptions extends SubscribeOptions { + /** + * An instance of PushSubscribeOptions with all the default options. + */ public static final PushSubscribeOptions DEFAULT_PUSH_OPTS = PushSubscribeOptions.builder().build(); private PushSubscribeOptions(Builder builder, String deliverSubject, String deliverGroup, @@ -104,6 +107,11 @@ public static class Builder private long pendingMessageLimit = Consumer.DEFAULT_MAX_MESSAGES; private long pendingByteLimit = Consumer.DEFAULT_MAX_BYTES; + /** + * Construct an instance of the builder + */ + public Builder() {} + @Override protected Builder getThis() { return this; diff --git a/src/main/java/io/nats/client/ReadListener.java b/src/main/java/io/nats/client/ReadListener.java index c2b40e012..552379449 100644 --- a/src/main/java/io/nats/client/ReadListener.java +++ b/src/main/java/io/nats/client/ReadListener.java @@ -13,7 +13,23 @@ package io.nats.client; +/** + * A listener that allows the user to track messages as soon as they come in off the wire. + * Be aware that implementations tracking messages can slow down handing off of those messages to the subscriptions waiting for them + * if they take a significant time to process them. This class is really intended for debugging purposes. + */ public interface ReadListener { - void protocol(String op, String string); + /** + * Called when the message is specifically a protocol message + * @param op the protocol operation + * @param text the text associated with the protocol if there is any. May be null + */ + void protocol(String op, String text); + + /** + * Called when the message is any non-protocol message + * @param op the message operation + * @param message the actual message + */ void message(String op, Message message); } diff --git a/src/main/java/io/nats/client/Statistics.java b/src/main/java/io/nats/client/Statistics.java index 73957e9cc..b3aa6ec31 100644 --- a/src/main/java/io/nats/client/Statistics.java +++ b/src/main/java/io/nats/client/Statistics.java @@ -16,52 +16,61 @@ /** * Connections can provide an instance of Statistics, {@link Connection#getStatistics() getStatistics()}. The statistics * object provides information about key metrics related to the connection over its entire lifecycle. - * + * *

The Statistics toString() provides a summary of the statistics. */ public interface Statistics { /** + * the total number of pings that have been sent from this connection. * @return the total number of pings that have been sent from this connection. */ long getPings(); /** + * the total number of times this connection has tried to reconnect. * @return the total number of times this connection has tried to reconnect. */ long getReconnects(); /** + * the total number of messages dropped by this connection across all slow consumers. * @return the total number of messages dropped by this connection across all slow consumers. */ long getDroppedCount(); /** + * the total number of op +OKs received by this connection. * @return the total number of op +OKs received by this connection. */ long getOKs(); /** + * the total number of op -ERRs received by this connection. * @return the total number of op -ERRs received by this connection. */ long getErrs(); /** + * the total number of exceptions seen by this connection. * @return the total number of exceptions seen by this connection. */ long getExceptions(); /** + * the total number of requests sent by this connection. * @return the total number of requests sent by this connection. */ long getRequestsSent(); /** + * the total number of replies received by this connection. * @return the total number of replies received by this connection. */ long getRepliesReceived(); /** + * the total number of duplicate replies received by this connection. * @return the total number of duplicate replies received by this connection. * * NOTE: This is only counted if advanced stats are enabled. @@ -69,6 +78,7 @@ public interface Statistics { long getDuplicateRepliesReceived(); /** + * the total number of orphan replies received by this connection. * @return the total number of orphan replies received by this connection. * * NOTE: This is only counted if advanced stats are enabled. @@ -76,31 +86,37 @@ public interface Statistics { long getOrphanRepliesReceived(); /** + * the total number of messages that have come in to this connection. * @return the total number of messages that have come in to this connection. */ long getInMsgs(); /** + * the total number of messages that have gone out of this connection. * @return the total number of messages that have gone out of this connection. */ long getOutMsgs(); /** + * the total number of message bytes that have come in to this connection. * @return the total number of message bytes that have come in to this connection. */ long getInBytes(); /** + * the total number of message bytes that have gone out of this connection. * @return the total number of message bytes that have gone out of this connection. */ long getOutBytes(); /** + * the total number of outgoing message flushes by this connection. * @return the total number of outgoing message flushes by this connection. */ long getFlushCounter(); /** + * the count of outstanding of requests from this connection. * @return the count of outstanding of requests from this connection. */ long getOutstandingRequests(); diff --git a/src/main/java/io/nats/client/SubscribeOptions.java b/src/main/java/io/nats/client/SubscribeOptions.java index 7d00bec42..9eaf152a7 100644 --- a/src/main/java/io/nats/client/SubscribeOptions.java +++ b/src/main/java/io/nats/client/SubscribeOptions.java @@ -25,6 +25,9 @@ * The SubscribeOptions is the base class for PushSubscribeOptions and PullSubscribeOptions */ public abstract class SubscribeOptions { + /** + * Constant for the default ordered heartbeat time in milliseconds + */ public static final long DEFAULT_ORDERED_HEARTBEAT = 5000; protected final String stream; @@ -242,6 +245,8 @@ public String toString() { /** * PushSubscribeOptions can be created using a Builder. The builder supports chaining and will * create a default set of options if no methods are calls. + * @param The builder type + * @param The resulting option type */ protected static abstract class Builder { protected String stream; diff --git a/src/main/java/io/nats/client/Subscription.java b/src/main/java/io/nats/client/Subscription.java index 80017c967..d7de74c7c 100644 --- a/src/main/java/io/nats/client/Subscription.java +++ b/src/main/java/io/nats/client/Subscription.java @@ -39,17 +39,20 @@ public interface Subscription extends Consumer { /** - * @return the subject associated with this subscription, will be non-null + * the subject associated with this subscription, will be non-null + * @return the subject */ String getSubject(); /** - * @return the queue associated with this subscription, may be null. + * the queue associated with this subscription, may be null. + * @return the queue name */ String getQueueName(); /** - * @return the Dispatcher that owns this subscription, or null + * the Dispatcher that owns this subscription, or null + * @return the dispatcher instance */ Dispatcher getDispatcher(); diff --git a/src/main/java/io/nats/client/TimeTraceLogger.java b/src/main/java/io/nats/client/TimeTraceLogger.java index 6d8c51fde..07d04f91a 100644 --- a/src/main/java/io/nats/client/TimeTraceLogger.java +++ b/src/main/java/io/nats/client/TimeTraceLogger.java @@ -13,6 +13,14 @@ package io.nats.client; +/** + * Interface to allow debug logging of some connection time tracing + */ public interface TimeTraceLogger { + /** + * Trace the object + * @param format a format string for the args + * @param args the args + */ void trace(String format, Object... args); } diff --git a/src/main/java/io/nats/client/api/AccountStatistics.java b/src/main/java/io/nats/client/api/AccountStatistics.java index f650f3fbe..9c4c25324 100644 --- a/src/main/java/io/nats/client/api/AccountStatistics.java +++ b/src/main/java/io/nats/client/api/AccountStatistics.java @@ -35,6 +35,10 @@ public class AccountStatistics extends ApiResponse { private final ApiStats api; private final Map tiers; + /** + * Construct an AccountStatistics + * @param msg the api response message + */ public AccountStatistics(Message msg) { super(msg); rollupTier = new AccountTier(jv); diff --git a/src/main/java/io/nats/client/api/AckPolicy.java b/src/main/java/io/nats/client/api/AckPolicy.java index 529406b0a..a15f72548 100644 --- a/src/main/java/io/nats/client/api/AckPolicy.java +++ b/src/main/java/io/nats/client/api/AckPolicy.java @@ -37,6 +37,10 @@ public enum AckPolicy { private final String policy; + /** + * Construct an AckPolicy + * @param p the policy JSON value text + */ AckPolicy(String p) { policy = p; } @@ -54,6 +58,11 @@ public String toString() { } } + /** + * Get an instance of the AckPolicy or null if the string does not match the JSON value text + * @param value the value to look up + * @return the AckPolicy or null if not found + */ @Nullable public static AckPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/ApiResponse.java b/src/main/java/io/nats/client/api/ApiResponse.java index 146f95d41..93a046b1a 100644 --- a/src/main/java/io/nats/client/api/ApiResponse.java +++ b/src/main/java/io/nats/client/api/ApiResponse.java @@ -24,20 +24,43 @@ import static io.nats.client.support.ApiConstants.TYPE; import static io.nats.client.support.JsonValueUtils.*; +/** + * ApiResponse is the base class for all api responses from the server + * @param the success response class + */ public abstract class ApiResponse { + /** + * A constant for a response without a type + */ public static final String NO_TYPE = "io.nats.jetstream.api.v1.no_type"; + + /** + * a constant for a response that errors while parsing + */ public static final String PARSE_ERROR_TYPE = "io.nats.client.api.parse_error"; + /** + * The json value made from creating the object from a message or that was used to directly construct the response + */ protected final JsonValue jv; private final String type; private Error error; + /** + * construct an ApiResponse from a message + * @param msg the message + */ public ApiResponse(Message msg) { this(parseMessage(msg)); } + /** + * parse the response message + * @param msg the message + * @return the JsonValue of the parsed JSON + */ protected static JsonValue parseMessage(Message msg) { if (msg == null) { return null; @@ -53,6 +76,12 @@ protected static JsonValue parseMessage(Message msg) { } } + /** + * called when the JSON is invalid + * @param retVal the fluent value to return + * @return the return value + * @param the type of the return value + */ protected R invalidJson(R retVal) { // only set the error if it's not already set. // this can easily happen when the original response is a real error @@ -63,23 +92,46 @@ protected R invalidJson(R retVal) { return retVal; } + /** + * set an error if the value in the key is null + * @param jv the input + * @param key the key + * @return the value of the key + */ protected String nullStringIsError(JsonValue jv, String key) { String s = readString(jv, key); return s == null ? invalidJson("") : s; } + /** + * set an error if the value in the key is null + * @param jv the input + * @param key the key + * @return the value of the key + */ @SuppressWarnings("SameParameterValue") protected ZonedDateTime nullDateIsError(JsonValue jv, String key) { ZonedDateTime zdt = readDate(jv, key); return zdt == null ? invalidJson(DateTimeUtils.DEFAULT_TIME) : zdt; } + /** + * set an error if the value in the key is null + * @param jv the input + * @param key the key + * @param errorValue the value in case of error + * @return the value of the key + */ @SuppressWarnings("SameParameterValue") protected JsonValue nullValueIsError(JsonValue jv, String key, JsonValue errorValue) { JsonValue v = readValue(jv, key); return v == null ? invalidJson(errorValue) : v; } + /** + * Construct an ApiResponse from a JsonValue + * @param jsonValue the value + */ public ApiResponse(JsonValue jsonValue) { jv = jsonValue; if (jv == null) { @@ -99,18 +151,30 @@ public ApiResponse(JsonValue jsonValue) { } } + /** + * Construct an empty ApiResponse + */ public ApiResponse() { jv = null; error = null; type = NO_TYPE; } + /** + * Construct an ApiResponse from an error object + * @param error the error object + */ public ApiResponse(Error error) { jv = null; this.error = error; type = NO_TYPE; } + /** + * throw an Exception if the response had an error + * @return the ApiResponse if not an error + * @throws JetStreamApiException if the response had an error + */ @SuppressWarnings("unchecked") public T throwOnHasError() throws JetStreamApiException { if (error != null) { @@ -119,38 +183,70 @@ public T throwOnHasError() throws JetStreamApiException { return (T)this; } + /** + * Get the JsonValue used to make this object + * @return the value + */ @Nullable public JsonValue getJv() { return jv; } + /** + * Does the response have an error + * @return true if the response has an error + */ public boolean hasError() { return error != null; } + /** + * The type of the response object + * @return the type + */ @Nullable public String getType() { return type; } + /** + * The request error code from the server + * @return the code + */ public int getErrorCode() { return error == null ? Error.NOT_SET : error.getCode(); } + /** + * The api error code from the server + * @return the code + */ public int getApiErrorCode() { return error == null ? Error.NOT_SET : error.getApiErrorCode(); } + /** + * Get the error description + * @return the description if the response is an error + */ @Nullable public String getDescription() { return error == null ? null : error.getDescription(); } + /** + * Get the error object string + * @return the error object string if the response is an error + */ @Nullable public String getError() { return error == null ? null : error.toString(); } + /** + * Get the error object + * @return the error object if the response is an error + */ @Nullable public Error getErrorObject() { return error; diff --git a/src/main/java/io/nats/client/api/ApiStats.java b/src/main/java/io/nats/client/api/ApiStats.java index 4ccfd05ca..d982bc665 100644 --- a/src/main/java/io/nats/client/api/ApiStats.java +++ b/src/main/java/io/nats/client/api/ApiStats.java @@ -35,6 +35,10 @@ public class ApiStats { this.inFlight = JsonValueUtils.readLong(vApiStats, INFLIGHT, 0); } + /** + * The JetStream API Level + * @return the level + */ public int getLevel() { return level; } @@ -55,6 +59,10 @@ public long getErrorCount() { return errors; } + /** + * The number of inflight API requests waiting to be processed + * @return inflight API requests + */ public long getInFlight() { return inFlight; } diff --git a/src/main/java/io/nats/client/api/CompressionOption.java b/src/main/java/io/nats/client/api/CompressionOption.java index 541b19093..71a9d6b05 100644 --- a/src/main/java/io/nats/client/api/CompressionOption.java +++ b/src/main/java/io/nats/client/api/CompressionOption.java @@ -22,7 +22,14 @@ * Stream compression policies. */ public enum CompressionOption { + /** + * No compress + */ None("none"), + + /** + * S2 compression + */ S2("s2"); private final String policy; @@ -44,6 +51,11 @@ public String toString() { } } + /** + * Get an instance of the CompressionOption or null if the string does not match the JSON value text + * @param value the value to look up + * @return the CompressionOption or null if not found + */ @Nullable public static CompressionOption get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/ConsumerConfiguration.java b/src/main/java/io/nats/client/api/ConsumerConfiguration.java index d8d3c4c11..4f229b0ca 100644 --- a/src/main/java/io/nats/client/api/ConsumerConfiguration.java +++ b/src/main/java/io/nats/client/api/ConsumerConfiguration.java @@ -38,26 +38,79 @@ *

By default this will create a pull consumer unless {@link ConsumerConfiguration.Builder#deliverSubject(String) ConsumerConfiguration.Builder.deliverSubject(String) } is set. */ public class ConsumerConfiguration implements JsonSerializable { - @Deprecated - public static final Duration DURATION_MIN = Duration.ofNanos(1); - + /** + * The default deliver policy for consumers + */ public static final DeliverPolicy DEFAULT_DELIVER_POLICY = DeliverPolicy.All; + + /** + * The default ack policy for consumers + */ public static final AckPolicy DEFAULT_ACK_POLICY = AckPolicy.Explicit; + + /** + * The default replay policy for consumers + */ public static final ReplayPolicy DEFAULT_REPLAY_POLICY = ReplayPolicy.Instant; + + /** + * The default priority policy for consumers + */ public static final PriorityPolicy DEFAULT_PRIORITY_POLICY = PriorityPolicy.None; - public static final Duration DURATION_UNSET = Duration.ZERO; + /** + * The minimum allowed idle heartbeat setting + */ public static final Duration MIN_IDLE_HEARTBEAT = Duration.ofMillis(100); + /** + * Constant used to unset a Duration setting in the builder + */ + public static final Duration DURATION_UNSET = Duration.ZERO; + + /** + * Constant used to unset a Duration setting in the builder + */ public static final int INTEGER_UNSET = -1; + + /** + * Constant used to unset a long setting in the builder + */ public static final long LONG_UNSET = -1; + + /** + * Constant used to unset a long that represents an unsigned long setting in the builder + */ public static final long ULONG_UNSET = 0; + + /** + * Constant used to unset a long setting in the builder + */ public static final long DURATION_UNSET_LONG = 0; + + /** + * Constant used to unset a Duration setting in the builder + */ public static final long DURATION_MIN_LONG = 1; + + /** + * Constant used to as a standard minimum value + */ public static final int STANDARD_MIN = 0; + + /** + * Constant representing the minimum max deliver + */ public static final int MAX_DELIVER_MIN = 1; + /** + * Constant representing the minimum idle heartbeat in nanos + */ public static final long MIN_IDLE_HEARTBEAT_NANOS = MIN_IDLE_HEARTBEAT.toNanos(); + + /** + * Constant representing the minimum idle heartbeat in milliseconds + */ public static final long MIN_IDLE_HEARTBEAT_MILLIS = MIN_IDLE_HEARTBEAT.toMillis(); protected final DeliverPolicy deliverPolicy; @@ -791,7 +844,7 @@ public Builder(ConsumerConfiguration cc) { * Initialize values from the json string. * @param json the json string to parse * @return the builder - * @throws JsonParseException if the json is invalid + * @throws JsonParseException if there is a problem parsing the json */ public Builder json(String json) throws JsonParseException { return jsonValue(JsonParser.parse(json)); @@ -1576,4 +1629,10 @@ protected static Duration normalizeDuration(long millis) protected static AckPolicy GetOrDefault(AckPolicy p) { return p == null ? DEFAULT_ACK_POLICY : p; } protected static ReplayPolicy GetOrDefault(ReplayPolicy p) { return p == null ? DEFAULT_REPLAY_POLICY : p; } protected static PriorityPolicy GetOrDefault(PriorityPolicy p) { return p == null ? DEFAULT_PRIORITY_POLICY : p; } + + /** + * Not used + */ + @Deprecated + public static final Duration DURATION_MIN = Duration.ofNanos(1); } diff --git a/src/main/java/io/nats/client/api/ConsumerInfo.java b/src/main/java/io/nats/client/api/ConsumerInfo.java index 5236a0343..ab8dbd9ad 100644 --- a/src/main/java/io/nats/client/api/ConsumerInfo.java +++ b/src/main/java/io/nats/client/api/ConsumerInfo.java @@ -49,12 +49,20 @@ public class ConsumerInfo extends ApiResponse { private final ZonedDateTime timestamp; private final List priorityGroupStates; + /** + * Construct a ConsumerInfo instance from a message + * @param msg the message + */ public ConsumerInfo(Message msg) { this(parseMessage(msg)); } - public ConsumerInfo(JsonValue vConsumerInfo) { - super(vConsumerInfo); + /** + * Construct a ConsumerInfo instance from a JsonValue + * @param jsonValue the JsonValue + */ + public ConsumerInfo(JsonValue jsonValue) { + super(jsonValue); if (hasError()) { this.configuration = ConsumerConfiguration.builder().build(); stream = UNDEFINED; @@ -74,29 +82,29 @@ public ConsumerInfo(JsonValue vConsumerInfo) { priorityGroupStates = null; } else { - JsonValue jvConfig = nullValueIsError(jv, CONFIG, JsonValue.EMPTY_MAP) ; + JsonValue jvConfig = nullValueIsError(this.jv, CONFIG, JsonValue.EMPTY_MAP) ; configuration = ConsumerConfiguration.builder().jsonValue(jvConfig).build(); - stream = nullStringIsError(jv, STREAM_NAME); - name = nullStringIsError(jv, NAME); - created = nullDateIsError(jv, CREATED); + stream = nullStringIsError(this.jv, STREAM_NAME); + name = nullStringIsError(this.jv, NAME); + created = nullDateIsError(this.jv, CREATED); - delivered = new SequenceInfo(readObject(jv, DELIVERED)); - ackFloor = new SequenceInfo(readObject(jv, ACK_FLOOR)); + delivered = new SequenceInfo(readObject(this.jv, DELIVERED)); + ackFloor = new SequenceInfo(readObject(this.jv, ACK_FLOOR)); - numAckPending = readLong(jv, NUM_ACK_PENDING, 0); - numRedelivered = readLong(jv, NUM_REDELIVERED, 0); - numPending = readLong(jv, NUM_PENDING, 0); - numWaiting = readLong(jv, NUM_WAITING, 0); - paused = readBoolean(jv, PAUSED, false); - pauseRemaining = readNanos(jv, PAUSE_REMAINING); + numAckPending = readLong(this.jv, NUM_ACK_PENDING, 0); + numRedelivered = readLong(this.jv, NUM_REDELIVERED, 0); + numPending = readLong(this.jv, NUM_PENDING, 0); + numWaiting = readLong(this.jv, NUM_WAITING, 0); + paused = readBoolean(this.jv, PAUSED, false); + pauseRemaining = readNanos(this.jv, PAUSE_REMAINING); - clusterInfo = ClusterInfo.optionalInstance(readValue(jv, CLUSTER)); - pushBound = readBoolean(jv, PUSH_BOUND); + clusterInfo = ClusterInfo.optionalInstance(readValue(this.jv, CLUSTER)); + pushBound = readBoolean(this.jv, PUSH_BOUND); - timestamp = readDate(jv, TIMESTAMP); + timestamp = readDate(this.jv, TIMESTAMP); - priorityGroupStates = PriorityGroupState.optionalListOf(readObject(jv, PRIORITY_GROUPS)); + priorityGroupStates = PriorityGroupState.optionalListOf(readObject(this.jv, PRIORITY_GROUPS)); } } diff --git a/src/main/java/io/nats/client/api/ConsumerLimits.java b/src/main/java/io/nats/client/api/ConsumerLimits.java index f6ae84263..edd46254a 100644 --- a/src/main/java/io/nats/client/api/ConsumerLimits.java +++ b/src/main/java/io/nats/client/api/ConsumerLimits.java @@ -91,6 +91,11 @@ public static class Builder { private Duration inactiveThreshold; private Integer maxAckPending; + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * sets the amount of time before the consumer is deemed inactive. * @param inactiveThreshold the threshold duration diff --git a/src/main/java/io/nats/client/api/ConsumerPauseRequest.java b/src/main/java/io/nats/client/api/ConsumerPauseRequest.java index f81978f36..b25484419 100644 --- a/src/main/java/io/nats/client/api/ConsumerPauseRequest.java +++ b/src/main/java/io/nats/client/api/ConsumerPauseRequest.java @@ -27,6 +27,10 @@ public class ConsumerPauseRequest implements JsonSerializable { private final ZonedDateTime pauseUntil; + /** + * Construct a consumer pause request with the time requested to pause + * @param pauseUntil the time + */ public ConsumerPauseRequest(ZonedDateTime pauseUntil) { this.pauseUntil = pauseUntil; } diff --git a/src/main/java/io/nats/client/api/ConsumerPauseResponse.java b/src/main/java/io/nats/client/api/ConsumerPauseResponse.java index 7d8c9bb41..789c26b65 100644 --- a/src/main/java/io/nats/client/api/ConsumerPauseResponse.java +++ b/src/main/java/io/nats/client/api/ConsumerPauseResponse.java @@ -22,12 +22,19 @@ import static io.nats.client.support.ApiConstants.*; import static io.nats.client.support.JsonValueUtils.*; +/** + * The response for a ConsumerPauseRequest + */ public class ConsumerPauseResponse extends ApiResponse { private final boolean paused; private final ZonedDateTime pauseUntil; private final Duration pauseRemaining; + /** + * Construct a ConsumerPauseResponse instance from a message + * @param msg the message + */ public ConsumerPauseResponse(Message msg) { super(msg); paused = readBoolean(jv, PAUSED); diff --git a/src/main/java/io/nats/client/api/DeliverPolicy.java b/src/main/java/io/nats/client/api/DeliverPolicy.java index 6f37b7c3a..f6c74dd70 100644 --- a/src/main/java/io/nats/client/api/DeliverPolicy.java +++ b/src/main/java/io/nats/client/api/DeliverPolicy.java @@ -19,14 +19,25 @@ import java.util.Map; /** - * The delivery policy for this consumer. + * The delivery policy for this consumer, the point in the stream from which to receive messages */ public enum DeliverPolicy { + /** all messages */ All("all"), + + /** start at the last message */ Last("last"), + + /** start at any new messages */ New("new"), + + /** by start sequence */ ByStartSequence("by_start_sequence"), + + /** by start time */ ByStartTime("by_start_time"), + + /** last per subject */ LastPerSubject("last_per_subject"); private final String policy; @@ -48,6 +59,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static DeliverPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/DiscardPolicy.java b/src/main/java/io/nats/client/api/DiscardPolicy.java index 1c291eca3..05c4abd87 100644 --- a/src/main/java/io/nats/client/api/DiscardPolicy.java +++ b/src/main/java/io/nats/client/api/DiscardPolicy.java @@ -22,7 +22,9 @@ * Stream discard policies */ public enum DiscardPolicy { + /** discard new messages */ New("new"), + /** discard old messages */ Old("old"); private final String policy; @@ -44,6 +46,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static DiscardPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/Error.java b/src/main/java/io/nats/client/api/Error.java index 9def404a0..ab785a7c2 100644 --- a/src/main/java/io/nats/client/api/Error.java +++ b/src/main/java/io/nats/client/api/Error.java @@ -26,6 +26,9 @@ */ public class Error implements JsonSerializable { + /** + * represents an error code that was not set / provided + */ public static final int NOT_SET = -1; private final JsonValue jv; @@ -62,14 +65,26 @@ public JsonValue toJsonValue() { return jv; } + /** + * The request error code from the server + * @return the code + */ public int getCode() { return JsonValueUtils.readInteger(jv, CODE, NOT_SET); } + /** + * The api error code from the server + * @return the code + */ public int getApiErrorCode() { return JsonValueUtils.readInteger(jv, ERR_CODE, NOT_SET); } + /** + * Get the error description + * @return the description + */ @NonNull public String getDescription() { return JsonValueUtils.readString(jv, DESCRIPTION, "Unknown JetStream Error"); @@ -91,6 +106,11 @@ public String toString() { return getDescription() + " [" + apiErrorCode + "]"; } + /** + * Convert a status to an Error object. Only some status are supported, otherwise a generic error is returned + * @param status the status + * @return the error + */ @NonNull public static Error convert(Status status) { switch (status.getCode()) { diff --git a/src/main/java/io/nats/client/api/External.java b/src/main/java/io/nats/client/api/External.java index 2d5497bb3..961273561 100644 --- a/src/main/java/io/nats/client/api/External.java +++ b/src/main/java/io/nats/client/api/External.java @@ -49,6 +49,14 @@ public External(String api, String deliver) { this.deliver = deliver; } + /** + * Construct an External configuration copying the information from an External configuration + * @param external the source configuration + */ + public External(External external) { + this.api = external.api; + this.deliver = external.deliver; + } /** * Returns a JSON representation of this mirror * @@ -116,12 +124,17 @@ public static Builder builder() { } /** - * Placement can be created using a Builder. + * External can be created using a Builder. */ public static class Builder { private String api; private String deliver; + /** + * Construct a builder for an External object + */ + public Builder() {} + /** * Set the api string. * @param api the api diff --git a/src/main/java/io/nats/client/api/FeatureConfiguration.java b/src/main/java/io/nats/client/api/FeatureConfiguration.java index 62c1fe88b..9d2dbca85 100644 --- a/src/main/java/io/nats/client/api/FeatureConfiguration.java +++ b/src/main/java/io/nats/client/api/FeatureConfiguration.java @@ -25,6 +25,9 @@ import static io.nats.client.support.Validator.validateBucketName; import static io.nats.client.support.Validator.validateMaxBucketBytes; +/** + * base class for feature configurations + */ public abstract class FeatureConfiguration implements JsonSerializable { protected static final CompressionOption JS_COMPRESSION_YES = CompressionOption.S2; protected static final CompressionOption JS_COMPRESSION_NO = CompressionOption.None; @@ -54,6 +57,11 @@ public JsonValue toJsonValue() { return mb.toJsonValue(); } + /** + * Construct a FeatureConfiguration from a StreamConfiguration and a bucket name + * @param sc the StreamConfiguration + * @param bucketName the bucket name + */ public FeatureConfiguration(StreamConfiguration sc, String bucketName) { this.sc = sc; this.bucketName = bucketName; diff --git a/src/main/java/io/nats/client/api/KeyResult.java b/src/main/java/io/nats/client/api/KeyResult.java index ee097b445..8c3532d8b 100644 --- a/src/main/java/io/nats/client/api/KeyResult.java +++ b/src/main/java/io/nats/client/api/KeyResult.java @@ -14,44 +14,78 @@ import org.jspecify.annotations.Nullable; +/** + * Class is used as the result or consuming keys + */ public class KeyResult { private final String key; private final Exception e; + /** + * Construct a valueless Key Result - used as the done marker without an exception + */ public KeyResult() { this.key = null; this.e = null; } + /** + * Construct a key result for a specific key + * @param key the key + */ public KeyResult(String key) { this.key = key; this.e = null; } + /** + * Construct a key result containing an exception + * @param e the exception + */ public KeyResult(Exception e) { this.key = null; this.e = e; } + /** + * Get the key in this result + * @return the key or null if there is no key + */ @Nullable public String getKey() { return key; } + /** + * Get the exception in this result + * @return the exception or null if there is no exception + */ @Nullable public Exception getException() { return e; } + /** + * Whether this result is a key. + * @return true if the result is a key + */ public boolean isKey() { return key != null; } + /** + * Whether this result is an exception + * @return true if the result is an exception + */ public boolean isException() { return e != null; } + /** + * If there is no key, the result indicates the consume is done, even if there is an exception. + * @return true if this result indicates the consume is done. + */ public boolean isDone() { return key == null; } diff --git a/src/main/java/io/nats/client/api/KeyValueEntry.java b/src/main/java/io/nats/client/api/KeyValueEntry.java index 62e5e1e4b..ef420ff12 100644 --- a/src/main/java/io/nats/client/api/KeyValueEntry.java +++ b/src/main/java/io/nats/client/api/KeyValueEntry.java @@ -38,8 +38,15 @@ public class KeyValueEntry { private final long delta; private final KeyValueOperation op; + /** + * Construct KeyValueEntry from message info + * @param mi the message info + */ public KeyValueEntry(MessageInfo mi) { Headers h = mi.getHeaders(); + if (mi.getSubject() == null) { + throw new IllegalStateException("Invalid Message Info"); + } bucketAndKey = new BucketAndKey(mi.getSubject()); value = extractValue(mi.getData()); dataLen = calculateLength(value, h); @@ -49,6 +56,10 @@ public KeyValueEntry(MessageInfo mi) { op = NatsKeyValueUtil.getOperation(h); } + /** + * Construct KeyValueEntry from a message + * @param m the message + */ public KeyValueEntry(Message m) { Headers h = m.getHeaders(); bucketAndKey = new BucketAndKey(m.getSubject()); @@ -60,47 +71,88 @@ public KeyValueEntry(Message m) { op = NatsKeyValueUtil.getOperation(h); } + /** + * Get the key value bucket this key in. + * @return the bucket + */ @NonNull public String getBucket() { return bucketAndKey.bucket; } + /** + * Get the key + * @return the key + */ @NonNull public String getKey() { return bucketAndKey.key; } + /** + * Get the value. May be null + * @return the value + */ public byte @Nullable [] getValue() { return value; } + /** + * Get the value as a string using UTF-8 encoding + * @return the value as a string or null if there is no value + */ @Nullable public String getValueAsString() { return value == null ? null : new String(value, UTF_8); } + /** + * Get the value as a long + * @return the value or null if there is no value + * @throws NumberFormatException if the string does not contain a parsable {@code long}. + */ @Nullable public Long getValueAsLong() { return value == null ? null : Long.parseLong(new String(value, ISO_8859_1)); } + /** + * Get the number of bytes in the data. May be zero + * @return the number of bytes + */ public long getDataLen() { return dataLen; } + /** + * Get the creation time of the current version of the key + * @return the creation time + */ @NonNull public ZonedDateTime getCreated() { return created; } + /** + * Get the revision number of the string. Not a version, but an internally strictly monotonical value + * @return the revision + */ public long getRevision() { return revision; } + /** + * Internal reference to pending message from the entry request + * @return the delta + */ public long getDelta() { return delta; } + /** + * The KeyValueOperation of this entry + * @return the operation + */ @NonNull public KeyValueOperation getOperation() { return op; diff --git a/src/main/java/io/nats/client/api/KeyValueOperation.java b/src/main/java/io/nats/client/api/KeyValueOperation.java index 1ae4a96b4..1e78bd5c1 100644 --- a/src/main/java/io/nats/client/api/KeyValueOperation.java +++ b/src/main/java/io/nats/client/api/KeyValueOperation.java @@ -18,7 +18,12 @@ * Key Value Operations Enum */ public enum KeyValueOperation { - PUT("PUT"), DELETE("DEL"), PURGE("PURGE"); + /** Put operation */ + PUT("PUT"), + /** Delete operation */ + DELETE("DEL"), + /** Purge operation */ + PURGE("PURGE"); private final String headerValue; @@ -26,10 +31,19 @@ public enum KeyValueOperation { this.headerValue = headerValue; } + /** + * Get the value used in the header + * @return the value + */ public String getHeaderValue() { return headerValue; } + /** + * Get an instance from the string value + * @param s the value + * @return the instance or the null if the string is not matched + */ @Nullable public static KeyValueOperation instance(String s) { if (PUT.headerValue.equals(s)) return PUT; @@ -38,12 +52,23 @@ public static KeyValueOperation instance(String s) { return null; } + /** + * Get an instance from the string value or the default + * @param s the value + * @param dflt the value if the string is not matched + * @return the instance or the default if the string is not matched + */ @Nullable public static KeyValueOperation getOrDefault(String s, KeyValueOperation dflt) { KeyValueOperation kvo = instance(s); return kvo == null ? dflt : kvo; } + /** + * Get an instance based on marker reason + * @param markerReason the markerReason + * @return the instance or null if the markerReason is not matched + */ @Nullable public static KeyValueOperation instanceByMarkerReason(String markerReason) { if ("Remove".equals(markerReason)) { diff --git a/src/main/java/io/nats/client/api/KeyValuePurgeOptions.java b/src/main/java/io/nats/client/api/KeyValuePurgeOptions.java index 48706fcd2..1e517775a 100644 --- a/src/main/java/io/nats/client/api/KeyValuePurgeOptions.java +++ b/src/main/java/io/nats/client/api/KeyValuePurgeOptions.java @@ -15,6 +15,9 @@ import java.time.Duration; +/** + * Options used when purging keys + */ public class KeyValuePurgeOptions { /** @@ -47,13 +50,16 @@ public static Builder builder() { /** * KeyValuePurgeOptions is created using a Builder. The builder supports chaining and will * create a default set of options if no methods are calls. - * - *

{@code new KeyValuePurgeOptions.Builder().build()} will create a new KeyValuePurgeOptions. - * + *

{@code new KeyValuePurgeOptions.Builder().build()} will create a new KeyValuePurgeOptions.

*/ public static class Builder { private long deleteMarkersThresholdMillis = DEFAULT_THRESHOLD_MILLIS; + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * Set the delete marker threshold. * Null or duration of 0 will assume the default threshold {@link #DEFAULT_THRESHOLD_MILLIS} diff --git a/src/main/java/io/nats/client/api/KeyValueStatus.java b/src/main/java/io/nats/client/api/KeyValueStatus.java index 606a25b4b..9441897e4 100644 --- a/src/main/java/io/nats/client/api/KeyValueStatus.java +++ b/src/main/java/io/nats/client/api/KeyValueStatus.java @@ -27,6 +27,10 @@ public class KeyValueStatus { private final StreamInfo streamInfo; private final KeyValueConfiguration config; + /** + * Construct an instance from the underlying stream info + * @param si the stream info + */ public KeyValueStatus(StreamInfo si) { streamInfo = si; config = new KeyValueConfiguration(streamInfo.getConfiguration()); diff --git a/src/main/java/io/nats/client/api/KeyValueWatchOption.java b/src/main/java/io/nats/client/api/KeyValueWatchOption.java index 525493fb4..5cd368466 100644 --- a/src/main/java/io/nats/client/api/KeyValueWatchOption.java +++ b/src/main/java/io/nats/client/api/KeyValueWatchOption.java @@ -12,6 +12,9 @@ // limitations under the License. package io.nats.client.api; +/** + * Options for the Key Value Watcher + */ public enum KeyValueWatchOption { /** * Do not include deletes or purges in results. diff --git a/src/main/java/io/nats/client/api/Mirror.java b/src/main/java/io/nats/client/api/Mirror.java index 7c56d9543..2b464318e 100644 --- a/src/main/java/io/nats/client/api/Mirror.java +++ b/src/main/java/io/nats/client/api/Mirror.java @@ -33,26 +33,49 @@ static Mirror optionalInstance(JsonValue vMirror) { super(b); } + /** + * Create an instance of the Mirror.Builder + * @return the instance + */ public static Builder builder() { return new Builder(); } + /** + * Create an instance of the Mirror.Builder with a copy of all the information in the source mirror + * @param mirror the source mirror + * @return the instance + */ public static Builder builder(Mirror mirror) { return new Builder(mirror); } + /** + * The builder for a Mirror + */ public static class Builder extends SourceBaseBuilder { @Override Builder getThis() { return this; } + /** + * Construct a builder + */ public Builder() {} + /** + * Construct a builder with a copy of all the information in the source mirror + * @param mirror the source mirror + */ public Builder(Mirror mirror) { super(mirror); } + /** + * Build the mirror from the builder + * @return the Mirror + */ public Mirror build() { return new Mirror(this); } diff --git a/src/main/java/io/nats/client/api/ObjectInfo.java b/src/main/java/io/nats/client/api/ObjectInfo.java index d88e8922b..766be7862 100644 --- a/src/main/java/io/nats/client/api/ObjectInfo.java +++ b/src/main/java/io/nats/client/api/ObjectInfo.java @@ -49,10 +49,18 @@ private ObjectInfo(Builder b) { objectMeta = b.metaBuilder.build(); } + /** + * Construct ObjectInfo from message info + * @param mi the message info + */ public ObjectInfo(MessageInfo mi) { this(mi.getData(), mi.getTime()); } + /** + * Construct ObjectInfo from a message + * @param m the message + */ public ObjectInfo(Message m) { this(m.getData(), m.metaData().timestamp()); } @@ -84,34 +92,62 @@ public String toJson() { return endJson(sb).toString(); } + /** + * the bucket name + * @return the name + */ @NonNull public String getBucket() { return bucket; } + /** + * the bucket nuid + * @return the nuid + */ @Nullable public String getNuid() { return nuid; } + /** + * The size of the object + * @return the size in bytes + */ public long getSize() { return size; } + /** + * When the object was last modified + * @return the last modified date + */ @Nullable public ZonedDateTime getModified() { return modified; } + /** + * The total number of chunks in the object + * @return the number of chunks + */ public long getChunks() { return chunks; } + /** + * The digest string for the object + * @return the digest + */ @Nullable public String getDigest() { return digest; } + /** + * Whether the object is deleted + * @return the deleted state + */ public boolean isDeleted() { return deleted; } @@ -178,18 +214,38 @@ public ObjectLink getLink() { return objectMeta.getObjectMetaOptions() == null ? null : objectMeta.getObjectMetaOptions().getLink(); } + /** + * Get an instance of the builder initialized with a bucket and object meta + * @param bucket the bucket name + * @param objectName the object name + * @return the builder + */ public static Builder builder(String bucket, String objectName) { return new Builder(bucket, objectName); } + /** + * Get an instance of the builder initialized with a bucket and object meta + * @param bucket the bucket + * @param meta the object meta + * @return the builder + */ public static Builder builder(String bucket, ObjectMeta meta) { return new Builder(bucket, meta); } + /** + * Get an instance of the builder initialized from existing ObjectInfo + * @param info the info + * @return the builder + */ public static Builder builder(ObjectInfo info) { return new Builder(info); } + /** + * A builder for ObjectInfo + */ public static class Builder { String bucket; String nuid; @@ -200,16 +256,30 @@ public static class Builder { boolean deleted; ObjectMeta.Builder metaBuilder; + /** + * Construct the builder initialized with a bucket and object name + * @param bucket the bucket name + * @param objectName the object name + */ public Builder(String bucket, String objectName) { metaBuilder = ObjectMeta.builder(objectName); bucket(bucket); } + /** + * Construct the builder initialized with a bucket and object meta + * @param bucket the bucket name + * @param meta the object meta + */ public Builder(String bucket, ObjectMeta meta) { metaBuilder = ObjectMeta.builder(meta); bucket(bucket); } + /** + * Construct the builder initialized from existing ObjectInfo + * @param info the info + */ public Builder(ObjectInfo info) { bucket = info.bucket; nuid = info.nuid; @@ -221,86 +291,171 @@ public Builder(ObjectInfo info) { metaBuilder = ObjectMeta.builder(info.objectMeta); } + /** + * set the object name + * @param name the name + * @return the builder + */ public Builder objectName(String name) { metaBuilder.objectName(name); return this; } + /** + * set the object's bucket name + * @param bucket the bucket name + * @return the builder + */ public Builder bucket(String bucket) { this.bucket = Validator.validateBucketName(bucket, true); return this; } + /** + * set the object's nuid + * @param nuid the nuid + * @return the builder + */ public Builder nuid(String nuid) { this.nuid = nuid; return this; } + /** + * set the object's size + * @param size the size + * @return the builder + */ public Builder size(long size) { this.size = size; return this; } + /** + * set the object's modified time + * @param modified the time + * @return the builder + */ public Builder modified(ZonedDateTime modified) { this.modified = modified; return this; } + /** + * set the object's number of chunks + * @param chunks the number of chunks + * @return the builder + */ public Builder chunks(long chunks) { this.chunks = chunks; return this; } + /** + * set the object's digest + * @param digest the digest + * @return the builder + */ public Builder digest(String digest) { this.digest = digest; return this; } + /** + * set the object's deleted state + * @param deleted the state + * @return the builder + */ public Builder deleted(boolean deleted) { this.deleted = deleted; return this; } + /** + * convenience method to set the object's ObjectMeta description + * @param description the description text + * @return the builder + */ public Builder description(String description) { metaBuilder.description(description); return this; } + /** + * convenience method to set the object's ObjectMeta headers + * @param headers the headers + * @return the builder + */ public Builder headers(Headers headers) { metaBuilder.headers(headers); return this; } + /** + * convenience method to set the object's ObjectMeta meta data + * @param metadata the meta data + * @return the builder + */ public Builder metadata(Map metadata) { metaBuilder.metadata(metadata); return this; } + /** + * convenience method to set the object's ObjectMeta meta options + * @param objectMetaOptions the options + * @return the builder + */ public Builder options(ObjectMetaOptions objectMetaOptions) { metaBuilder.options(objectMetaOptions); return this; } + /** + * convenience method to set the object's ObjectMeta chunk size + * @param chunkSize the size of the chunks + * @return the builder + */ public Builder chunkSize(int chunkSize) { metaBuilder.chunkSize(chunkSize); return this; } + /** + * convenience method to set the object's ObjectMeta link + * @param link the link + * @return the builder + */ public Builder link(ObjectLink link) { metaBuilder.link(link); return this; } + /** + * convenience method to set the object's ObjectMeta link bucket name + * @param bucket the link bucket name + * @return the builder + */ public Builder bucketLink(String bucket) { metaBuilder.link(ObjectLink.bucket(bucket)); return this; } + /** + * convenience method to set the object's ObjectMeta link + * @param bucket the link's bucket name + * @param objectName the link's object name + * @return the builder + */ public Builder objectLink(String bucket, String objectName) { metaBuilder.link(ObjectLink.object(bucket, objectName)); return this; } + /** + * Build an ObjectInfo + * @return the ObjectInfo instance + */ public ObjectInfo build() { return new ObjectInfo(this); } diff --git a/src/main/java/io/nats/client/api/ObjectLink.java b/src/main/java/io/nats/client/api/ObjectLink.java index 8758e20b9..9d88220ed 100644 --- a/src/main/java/io/nats/client/api/ObjectLink.java +++ b/src/main/java/io/nats/client/api/ObjectLink.java @@ -56,28 +56,55 @@ public String toJson() { return endJson(sb).toString(); } + /** + * Get the bucket the linked object is in + * @return the bucket name + */ @NonNull public String getBucket() { return bucket; } + /** + * Get the name of the object for the link + * @return the object name + */ @Nullable public String getObjectName() { return objectName; } + /** + * True if the object is a link to an object versus a link to a bucket + * @return true if the object is a link + */ public boolean isObjectLink() { return objectName != null; } + /** + * True if the object is a bucket to an object versus a link to a link + * @return true if the object is a bucket + */ public boolean isBucketLink() { return objectName == null; } - public static ObjectLink bucket(String bucket) { + /** + * create a bucket link + * @param bucket the bucket name + * @return the ObjectLink + */ + public static ObjectLink bucket(@NonNull String bucket) { return new ObjectLink(bucket, null); } + /** + * create an object link + * @param bucket the bucket the object is in + * @param objectName the object name + * @return the ObjectLink + */ public static ObjectLink object(String bucket, String objectName) { return new ObjectLink(bucket, objectName); } diff --git a/src/main/java/io/nats/client/api/ObjectMeta.java b/src/main/java/io/nats/client/api/ObjectMeta.java index f87d0b57f..25b02b09a 100644 --- a/src/main/java/io/nats/client/api/ObjectMeta.java +++ b/src/main/java/io/nats/client/api/ObjectMeta.java @@ -129,18 +129,36 @@ public ObjectMetaOptions getObjectMetaOptions() { return objectMetaOptions; } + /** + * Get an instance of the ObjectMeta.Builder starting with the object name + * @param objectName the object name + * @return the builder + */ public static Builder builder(String objectName) { return new Builder(objectName); } + /** + * Get an instance of the ObjectMeta.Builder as a copy of existing meta + * @param om the existing meta + * @return the builder + */ public static Builder builder(ObjectMeta om) { return new Builder(om); } + /** + * Create object meta that only has the object name. Fairly common use case + * @param objectName the object name + * @return the ObjectMeta + */ public static ObjectMeta objectName(String objectName) { return new Builder(objectName).build(); } + /** + * The builder for ObjectMeta + */ public static class Builder { String objectName; String description; @@ -148,6 +166,10 @@ public static class Builder { Map metadata; ObjectMetaOptions.Builder metaOptionsBuilder; + /** + * Construct a builder starting with the object name + * @param objectName the object name + */ public Builder(String objectName) { headers = new Headers(); metadata = new HashMap<>(); @@ -155,6 +177,10 @@ public Builder(String objectName) { objectName(objectName); } + /** + * Construct a builder as a copy of existing meta + * @param om the existing meta + */ public Builder(ObjectMeta om) { objectName = om.objectName; description = om.description; @@ -163,16 +189,31 @@ public Builder(ObjectMeta om) { metaOptionsBuilder = ObjectMetaOptions.builder(om.objectMetaOptions); } + /** + * Set the object name + * @param name the name + * @return the builder + */ public Builder objectName(String name) { this.objectName = Validator.validateNotNull(name, "Object Name"); return this; } + /** + * Set the object description + * @param description the description + * @return the builder + */ public Builder description(String description) { this.description = description; return this; } + /** + * Set the object headers + * @param headers the headers + * @return the builder + */ public Builder headers(Headers headers) { if (headers == null) { this.headers.clear(); @@ -183,6 +224,11 @@ public Builder headers(Headers headers) { return this; } + /** + * Set the object metadata + * @param metadata the metadata + * @return the builder + */ public Builder metadata(Map metadata) { if (metadata == null) { this.metadata.clear(); @@ -193,21 +239,40 @@ public Builder metadata(Map metadata) { return this; } + /** + * Set the object meta options + * @param objectMetaOptions the objectMetaOptions + * @return the builder + */ public Builder options(ObjectMetaOptions objectMetaOptions) { metaOptionsBuilder = ObjectMetaOptions.builder(objectMetaOptions); return this; } + /** + * Convenience method to set the ObjectMetaOptions chunk size + * @param chunkSize the size in bytes + * @return the builder + */ public Builder chunkSize(int chunkSize) { metaOptionsBuilder.chunkSize(chunkSize); return this; } + /** + * Convenience method to set the ObjectMetaOptions to set the link + * @param link the link + * @return the builder + */ public Builder link(ObjectLink link) { metaOptionsBuilder.link(link); return this; } + /** + * Build the Object Meta + * @return the ObjectMeta instance + */ public ObjectMeta build() { return new ObjectMeta(this); } diff --git a/src/main/java/io/nats/client/api/ObjectMetaOptions.java b/src/main/java/io/nats/client/api/ObjectMetaOptions.java index 9defb4c96..12b6d870e 100644 --- a/src/main/java/io/nats/client/api/ObjectMetaOptions.java +++ b/src/main/java/io/nats/client/api/ObjectMetaOptions.java @@ -52,15 +52,27 @@ public String toJson() { return endJson(sb).toString(); } + /** + * Whether the object is a link or has its own data + * @return true if it has data + */ boolean hasData() { return link != null || chunkSize > 0; } + /** + * Get the link this object refers to + * @return the link or null if this is not a link object + */ @Nullable public ObjectLink getLink() { return link; } + /** + * Get the chunk size + * @return the chunk size in bytes + */ public int getChunkSize() { return chunkSize; } @@ -73,27 +85,51 @@ static Builder builder(ObjectMetaOptions om) { return new Builder(om); } + /** + * The builder for ObjectMetaOptions + */ public static class Builder { ObjectLink link; int chunkSize; + /** + * Construct an ObjectMetaOptions.Builder + */ public Builder() {} + /** + * Construct an ObjectMetaOptions.Builder as a copy of existing options + * @param om the existing options + */ public Builder(ObjectMetaOptions om) { link = om.link; chunkSize = om.chunkSize; } + /** + * Set the link + * @param link the link + * @return the builder + */ public Builder link(ObjectLink link) { this.link = link; return this; } + /** + * Set the chunk size + * @param chunkSize the size in bytes + * @return the builder + */ public Builder chunkSize(int chunkSize) { this.chunkSize = chunkSize; return this; } + /** + * Build the ObjectMetaOptions + * @return the ObjectMetaOptions instance + */ public ObjectMetaOptions build() { return new ObjectMetaOptions(this); } diff --git a/src/main/java/io/nats/client/api/ObjectStoreStatus.java b/src/main/java/io/nats/client/api/ObjectStoreStatus.java index 3819a0275..90eca95c6 100644 --- a/src/main/java/io/nats/client/api/ObjectStoreStatus.java +++ b/src/main/java/io/nats/client/api/ObjectStoreStatus.java @@ -27,6 +27,10 @@ public class ObjectStoreStatus { private final StreamInfo streamInfo; private final ObjectStoreConfiguration config; + /** + * Create an object store from the StreamInfo for the underlying stream + * @param si the stream info + */ public ObjectStoreStatus(StreamInfo si) { streamInfo = si; config = new ObjectStoreConfiguration(streamInfo.getConfiguration()); diff --git a/src/main/java/io/nats/client/api/ObjectStoreWatchOption.java b/src/main/java/io/nats/client/api/ObjectStoreWatchOption.java index 3347271a0..c1eb2b0dc 100644 --- a/src/main/java/io/nats/client/api/ObjectStoreWatchOption.java +++ b/src/main/java/io/nats/client/api/ObjectStoreWatchOption.java @@ -13,6 +13,9 @@ package io.nats.client.api; +/** + * Options for the Object Store Watcher + */ public enum ObjectStoreWatchOption { /** * Do not include deletes or purges in results. diff --git a/src/main/java/io/nats/client/api/OrderedConsumerConfiguration.java b/src/main/java/io/nats/client/api/OrderedConsumerConfiguration.java index a7258b512..06090f26d 100644 --- a/src/main/java/io/nats/client/api/OrderedConsumerConfiguration.java +++ b/src/main/java/io/nats/client/api/OrderedConsumerConfiguration.java @@ -31,6 +31,9 @@ import static io.nats.client.support.Validator.emptyAsNull; import static io.nats.client.support.Validator.nullOrEmpty; +/** + * The ConsumerConfiguration class specifies the configuration for creating an ordered JetStream consumer + */ public class OrderedConsumerConfiguration implements JsonSerializable { private final List filterSubjects; @@ -52,18 +55,32 @@ public OrderedConsumerConfiguration() { filterSubjects.add(GREATER_THAN); } + /** + * OrderedConsumerConfiguration creation works like a builder. + * The builder supports chaining and will create a default set of options if + * no methods are calls, including setting the filter subject to > + * @param json the JSON used to seed the builder + * @throws JsonParseException if there is a problem parsing the json + */ public OrderedConsumerConfiguration(@NonNull String json) throws JsonParseException { this(JsonParser.parse(json)); } - public OrderedConsumerConfiguration(@NonNull JsonValue v) throws JsonParseException { + /** + * OrderedConsumerConfiguration creation works like a builder. + * The builder supports chaining and will create a default set of options if + * no methods are calls, including setting the filter subject to > + * @param jv the JsonValue used to seed the builder + * @throws JsonParseException if there is a problem parsing the json + */ + public OrderedConsumerConfiguration(@NonNull JsonValue jv) throws JsonParseException { this(); - filterSubjects(readStringList(v, FILTER_SUBJECTS)); // readStringList won't return null but can return empty - deliverPolicy(DeliverPolicy.get(readString(v, DELIVER_POLICY))); - startSequence(readLong(v, OPT_START_SEQ, ConsumerConfiguration.LONG_UNSET)); - startTime(readDate(v, OPT_START_TIME)); - replayPolicy(ReplayPolicy.get(readString(v, REPLAY_POLICY))); - headersOnly(readBoolean(v, HEADERS_ONLY, null)); + filterSubjects(readStringList(jv, FILTER_SUBJECTS)); // readStringList won't return null but can return empty + deliverPolicy(DeliverPolicy.get(readString(jv, DELIVER_POLICY))); + startSequence(readLong(jv, OPT_START_SEQ, ConsumerConfiguration.LONG_UNSET)); + startTime(readDate(jv, OPT_START_TIME)); + replayPolicy(ReplayPolicy.get(readString(jv, REPLAY_POLICY))); + headersOnly(readBoolean(jv, HEADERS_ONLY, null)); } /** @@ -198,49 +215,91 @@ public OrderedConsumerConfiguration consumerNamePrefix(String consumerNamePrefix return this; } + /** + * Gets the filter subject of this consumer configuration. + * With the introduction of multiple filter subjects, this method will + * return null if there are not exactly one filter subjects + * @return the first filter subject. + */ @Nullable public String getFilterSubject() { return filterSubjects.size() != 1 ? null : filterSubjects.get(0); } + /** + * Gets the filter subjects as a list. May be null, otherwise won't be empty + * @return the list + */ @NonNull public List getFilterSubjects() { return filterSubjects; } + /** + * Whether there are multiple filter subjects for this consumer configuration. + * @return true if there are multiple filter subjects + */ public boolean hasMultipleFilterSubjects() { return filterSubjects.size() > 1; } + /** + * Gets the deliver policy of this consumer configuration. + * @return the deliver policy. + */ @Nullable public DeliverPolicy getDeliverPolicy() { return deliverPolicy; } + /** + * Gets the start sequence of this consumer configuration. + * @return the start sequence. + */ @Nullable public Long getStartSequence() { return startSequence; } + /** + * Gets the start time of this consumer configuration. + * @return the start time. + */ @Nullable public ZonedDateTime getStartTime() { return startTime; } + /** + * Gets the replay policy of this consumer configuration. + * @return the replay policy. + */ @Nullable public ReplayPolicy getReplayPolicy() { return replayPolicy; } + /** + * Get the header only flag indicating whether it's on or off. Same as isHeadersOnly + * @return the flow control mode + */ @Nullable public Boolean getHeadersOnly() { return headersOnly; } + /** + * Get the header only flag indicating whether it's on or off. Same as getHeadersOnly + * @return the flow control mode + */ public boolean isHeadersOnly() { return headersOnly != null && headersOnly; } + /** + * Gets the prefix that will be used for names of underlying consumers + * @return the prefix + */ public String getConsumerNamePrefix() { return consumerNamePrefix; } diff --git a/src/main/java/io/nats/client/api/PeerInfo.java b/src/main/java/io/nats/client/api/PeerInfo.java index 102aac060..5b3095fe9 100644 --- a/src/main/java/io/nats/client/api/PeerInfo.java +++ b/src/main/java/io/nats/client/api/PeerInfo.java @@ -21,6 +21,9 @@ import static io.nats.client.support.ApiConstants.*; import static io.nats.client.support.JsonValueUtils.*; +/** + * Server peer information + */ public class PeerInfo { private final String name; diff --git a/src/main/java/io/nats/client/api/PersistMode.java b/src/main/java/io/nats/client/api/PersistMode.java index 20e354165..9092866db 100644 --- a/src/main/java/io/nats/client/api/PersistMode.java +++ b/src/main/java/io/nats/client/api/PersistMode.java @@ -23,7 +23,9 @@ * Stream persist modes */ public enum PersistMode { + /** default mode */ Default("default"), + /** async mode */ Async("async"); private final String mode; @@ -32,6 +34,10 @@ public enum PersistMode { this.mode = mode; } + /** + * get the mode JSON value string + * @return the mode + */ @NonNull public String getMode() { return mode; @@ -50,6 +56,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static PersistMode get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/Placement.java b/src/main/java/io/nats/client/api/Placement.java index ae39fb11a..b086963ef 100644 --- a/src/main/java/io/nats/client/api/Placement.java +++ b/src/main/java/io/nats/client/api/Placement.java @@ -55,6 +55,10 @@ public Placement(String cluster, List tags) { this.tags = tags == null || tags.isEmpty() ? null : tags; } + /** + * Whether the Placement has either a cluster or tags + * @return true if the Placement has data + */ public boolean hasData() { return cluster != null || tags != null; } @@ -109,6 +113,11 @@ public static class Builder { private String cluster; private List tags; + /** + * Construct a builder for Placement + */ + public Builder() {} + /** * Set the cluster string. * @param cluster the cluster diff --git a/src/main/java/io/nats/client/api/PriorityPolicy.java b/src/main/java/io/nats/client/api/PriorityPolicy.java index b76dccad8..a0bd5ba6c 100644 --- a/src/main/java/io/nats/client/api/PriorityPolicy.java +++ b/src/main/java/io/nats/client/api/PriorityPolicy.java @@ -22,9 +22,13 @@ * Represents the Priority Policy of a consumer */ public enum PriorityPolicy { + /** none */ None("none"), + /** overflow */ Overflow("overflow"), + /** prioritized */ Prioritized("prioritized"), + /** pinned_client */ PinnedClient("pinned_client"); private final String policy; @@ -46,6 +50,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static PriorityPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/PurgeResponse.java b/src/main/java/io/nats/client/api/PurgeResponse.java index 78fa15923..11fdfb093 100644 --- a/src/main/java/io/nats/client/api/PurgeResponse.java +++ b/src/main/java/io/nats/client/api/PurgeResponse.java @@ -20,11 +20,18 @@ import static io.nats.client.support.JsonValueUtils.readBoolean; import static io.nats.client.support.JsonValueUtils.readLong; +/** + * The response to a request to Purge a stream + */ public class PurgeResponse extends ApiResponse { private final boolean success; private final long purged; + /** + * Construct an instance of the PurgeResponse with the message + * @param msg the message + */ public PurgeResponse(Message msg) { super(msg); success = readBoolean(jv, SUCCESS); @@ -40,8 +47,8 @@ public boolean isSuccess() { } /** - * Returns the number of items purged from the stream * @deprecated + * Returns the number of items purged from the stream * This method is replaced since the purged value is a long * value, not an int value * See {@link #getPurged()} instead. @@ -49,7 +56,7 @@ public boolean isSuccess() { */ @Deprecated public int getPurgedCount() { - return new Long(purged).intValue(); + return Long.valueOf(purged).intValue(); } /** diff --git a/src/main/java/io/nats/client/api/ReplayPolicy.java b/src/main/java/io/nats/client/api/ReplayPolicy.java index e17f0aa6f..32efdded2 100644 --- a/src/main/java/io/nats/client/api/ReplayPolicy.java +++ b/src/main/java/io/nats/client/api/ReplayPolicy.java @@ -22,7 +22,9 @@ * Represents the replay policy of a consumer. */ public enum ReplayPolicy { + /** instant policy */ Instant("instant"), + /** original policy */ Original("original"); private String policy; @@ -44,6 +46,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static ReplayPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/Replica.java b/src/main/java/io/nats/client/api/Replica.java index fc7b5e6ac..06611c43f 100644 --- a/src/main/java/io/nats/client/api/Replica.java +++ b/src/main/java/io/nats/client/api/Replica.java @@ -18,6 +18,9 @@ import java.util.List; +/** + * Replica Peer Info + */ public class Replica extends PeerInfo { static List optionalListOf(JsonValue vReplicas) { diff --git a/src/main/java/io/nats/client/api/Republish.java b/src/main/java/io/nats/client/api/Republish.java index 7d0ff1a73..66b3b828e 100644 --- a/src/main/java/io/nats/client/api/Republish.java +++ b/src/main/java/io/nats/client/api/Republish.java @@ -107,6 +107,11 @@ public static class Builder { private String destination; private boolean headersOnly; + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * Set the Published Subject-matching filter * @param source the source diff --git a/src/main/java/io/nats/client/api/RetentionPolicy.java b/src/main/java/io/nats/client/api/RetentionPolicy.java index 9d41611a1..bc76cfa0e 100644 --- a/src/main/java/io/nats/client/api/RetentionPolicy.java +++ b/src/main/java/io/nats/client/api/RetentionPolicy.java @@ -22,8 +22,11 @@ * Stream retention policies. */ public enum RetentionPolicy { + /** Limits */ Limits("limits"), + /** Interest */ Interest("interest"), + /** Workqueue */ WorkQueue("workqueue"); private final String policy; @@ -45,6 +48,11 @@ public String toString() { } } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static RetentionPolicy get(String value) { return strEnumHash.get(value); diff --git a/src/main/java/io/nats/client/api/ServerInfo.java b/src/main/java/io/nats/client/api/ServerInfo.java index dbbd5700f..4b5297615 100644 --- a/src/main/java/io/nats/client/api/ServerInfo.java +++ b/src/main/java/io/nats/client/api/ServerInfo.java @@ -27,8 +27,15 @@ import static io.nats.client.support.JsonValueUtils.*; import static io.nats.client.support.NatsConstants.UNDEFINED; +/** + * Class holding information about a server + */ public class ServerInfo { + /** + * Constant representing an empty info. Used to ensure getting a ServerInfo from a connection is never null, + * it can be based on timing. + */ public static final ServerInfo EMPTY_INFO = new ServerInfo("INFO {}"); private final String serverId; @@ -51,6 +58,10 @@ public class ServerInfo { private final String clientIp; private final String cluster; + /** + * Construct a ServerInfo instance from json + * @param json the json + */ public ServerInfo(String json) { // INFO{ INFO<\t>{ or { if (json == null || json.length() < 6 || ('{' != json.charAt(0) && '{' != json.charAt(5))) { @@ -86,104 +97,205 @@ public ServerInfo(String json) { connectURLs = readStringListIgnoreEmpty(jv, CONNECT_URLS); } + /** + * true if server is in lame duck mode + * @return true if server is in lame duck mode + */ public boolean isLameDuckMode() { return lameDuckMode; } + /** + * the server id + * @return the server id + */ @NonNull public String getServerId() { return this.serverId; } + /** + * the server name + * @return the server name + */ @NonNull public String getServerName() { return serverName; } + /** + * the server version + * @return the server version + */ @NonNull public String getVersion() { return this.version; } + /** + * the go version the server is built with + * @return the go version the server is built with + */ @NonNull public String getGoVersion() { return this.go; } + /** + * the server host + * @return the server host + */ @NonNull public String getHost() { return this.host; } + /** + * the server port + * @return the server port + */ public int getPort() { return this.port; } + /** + * the server protocol version + * @return the server protocol version + */ public int getProtocolVersion() { return this.protocolVersion; } + /** + * true if headers are supported by the server + * @return true if headers are supported by the server + */ public boolean isHeadersSupported() { return this.headersSupported; } + /** + * true if authorization is required by the server + * @return true if authorization is required by the server + */ public boolean isAuthRequired() { return this.authRequired; } + /** + * true if TLS is required by the server + * @return true if TLS is required by the server + */ public boolean isTLSRequired() { return this.tlsRequired; } + /** + * true if TLS is available on the server + * @return true if TLS is available on the server + */ public boolean isTLSAvailable() { return tlsAvailable; } + /** + * the server configured max payload + * @return the max payload + */ public long getMaxPayload() { return this.maxPayload; } + /** + * the connectable urls in the cluster + * @return the connectable urls + */ @NonNull public List getConnectURLs() { return this.connectURLs; } + /** + * the nonce to use in authentication + * @return the nonce + */ public byte @Nullable [] getNonce() { return this.nonce; } + /** + * true if the server supports JetStream + * @return true if the server supports JetStream + */ public boolean isJetStreamAvailable() { return this.jetStream; } + /** + * the client id as determined by the server + * @return the client id + */ public int getClientId() { return clientId; } + /** + * the client ip address as determined by the server + * @return the client ip + */ @NonNull public String getClientIp() { return clientIp; } + /** + * the cluster name the server is in + * @return the cluster name + */ @Nullable public String getCluster() { return cluster; } + /** + * function to determine is the server version is newer than the input + * @param vTarget the target version to compare + * @return true if the server version is newer than the input + */ public boolean isNewerVersionThan(String vTarget) { return ServerVersion.isNewer(version, vTarget); } + /** + * function to determine is the server version is same as the input + * @param vTarget the target version to compare + * @return true if the server version is same as the input + */ public boolean isSameVersion(String vTarget) { return ServerVersion.isSame(version, vTarget); } + /** + * function to determine is the server version is older than the input + * @param vTarget the target version to compare + * @return true if the server version is older than the input + */ public boolean isOlderThanVersion(String vTarget) { return ServerVersion.isOlder(version, vTarget); } + /** + * function to determine is the server version is the same or older than the input + * @param vTarget the target version to compare + * @return true if the server version is the same or older than the input + */ public boolean isSameOrOlderThanVersion(String vTarget) { return ServerVersion.isSameOrOlder(version, vTarget); } + /** + * function to determine is the server version is same or newer than the input + * @param vTarget the target version to compare + * @return true if the server version is same or newer than the input + */ public boolean isSameOrNewerThanVersion(String vTarget) { return ServerVersion.isSameOrNewer(version, vTarget); } @@ -191,25 +303,26 @@ public boolean isSameOrNewerThanVersion(String vTarget) { @Override public String toString() { return "ServerInfo{" + - "serverId='" + serverId + '\'' + - ", serverName='" + serverName + '\'' + - ", version='" + version + '\'' + - ", go='" + go + '\'' + - ", host='" + host + '\'' + - ", port=" + port + - ", headersSupported=" + headersSupported + - ", authRequired=" + authRequired + - ", tlsRequired=" + tlsRequired + - ", tlsAvailable=" + tlsAvailable + - ", maxPayload=" + maxPayload + - ", connectURLs=" + connectURLs + - ", protocolVersion=" + protocolVersion + - ", nonce=" + Arrays.toString(nonce) + - ", lameDuckMode=" + lameDuckMode + - ", jetStream=" + jetStream + - ", clientId=" + clientId + - ", clientIp='" + clientIp + '\'' + - ", cluster='" + cluster + '\'' + - '}'; + "serverId='" + serverId + '\'' + + ", serverName='" + serverName + '\'' + + ", version='" + version + '\'' + + ", go='" + go + '\'' + + ", host='" + host + '\'' + + ", port=" + port + + ", headersSupported=" + headersSupported + + ", authRequired=" + authRequired + + ", tlsRequired=" + tlsRequired + + ", tlsAvailable=" + tlsAvailable + + ", maxPayload=" + maxPayload + + ", connectURLs=" + connectURLs + + ", protocolVersion=" + protocolVersion + + ", nonce=" + Arrays.toString(nonce) + + ", lameDuckMode=" + lameDuckMode + + ", jetStream=" + jetStream + + ", clientId=" + clientId + + ", clientIp='" + clientIp + '\'' + + ", cluster='" + cluster + '\'' + + '}'; } } + diff --git a/src/main/java/io/nats/client/api/Source.java b/src/main/java/io/nats/client/api/Source.java index 32c9314a6..887692299 100644 --- a/src/main/java/io/nats/client/api/Source.java +++ b/src/main/java/io/nats/client/api/Source.java @@ -35,26 +35,49 @@ static List optionalListOf(JsonValue vSources) { super(b); } + /** + * Get an instance of the builder + * @return the builder + */ public static Builder builder() { return new Builder(); } + /** + * Get an instance of the builder copying an existing source + * @param source the source + * @return the builder + */ public static Builder builder(Source source) { return new Builder(source); } + /** + * The builder for a Source + */ public static class Builder extends SourceBaseBuilder { @Override Builder getThis() { return this; } + /** + * Construct an instance of the builder + */ public Builder() {} + /** + * Construct an instance of the builder copying an existing source + * @param source the source + */ public Builder(Source source) { super(source); } + /** + * Build a Source + * @return the Source + */ public Source build() { return new Source(this); } diff --git a/src/main/java/io/nats/client/api/SourceBase.java b/src/main/java/io/nats/client/api/SourceBase.java index 83e24c6c4..6a2c428fc 100644 --- a/src/main/java/io/nats/client/api/SourceBase.java +++ b/src/main/java/io/nats/client/api/SourceBase.java @@ -34,6 +34,9 @@ import static io.nats.client.support.Validator.listsAreEquivalent; import static io.nats.client.support.Validator.nullOrEmpty; +/** + * A base class for sources + */ public abstract class SourceBase implements JsonSerializable { private final String name; private final long startSeq; @@ -95,25 +98,45 @@ public String getName() { return name; } + /** + * Get the configured start sequence + * @return the start sequence + */ public long getStartSeq() { return startSeq; } + /** + * Get the configured start time + * @return the start time + */ @Nullable public ZonedDateTime getStartTime() { return startTime; } + /** + * Get the configured filter subject + * @return the filter subject + */ @Nullable public String getFilterSubject() { return filterSubject; } + /** + * Get the External reference + * @return the External + */ @Nullable public External getExternal() { return external; } + /** + * Get the subject transforms + * @return the list of subject transforms + */ @Nullable public List getSubjectTransforms() { return subjectTransforms; @@ -124,6 +147,10 @@ public String toString() { return JsonUtils.toKey(getClass()) + toJson(); } + /** + * A builder base for objects that extend SourceBase + * @param the actual source type + */ public abstract static class SourceBaseBuilder { String name; long startSeq; @@ -134,53 +161,100 @@ public abstract static class SourceBaseBuilder { abstract T getThis(); + /** + * Construct an instance of the builder + */ public SourceBaseBuilder() {} + /** + * Construct an instance of the builder from a copy of another object that extends SourceBase + * @param base the base to copy + */ public SourceBaseBuilder(SourceBase base) { this.name = base.name; this.startSeq = base.startSeq; - this.startTime = base.startTime; + this.startTime = base.startTime; // zdt is immutable so copy is fine this.filterSubject = base.filterSubject; - this.external = base.external; - this.subjectTransforms = base.getSubjectTransforms(); + this.external = base.external == null ? null : new External(base.external); + this.subjectTransforms = base.getSubjectTransforms() == null ? null : new ArrayList<>(base.getSubjectTransforms()); } + /** + * Set the source name + * @param name the name + * @return the builder + */ public T sourceName(String name) { this.name = name; return getThis(); } + /** + * Set the source name. Same as sourceName + * @param name the name + * @return the builder + */ public T name(String name) { this.name = name; return getThis(); } + /** + * Set the start sequence + * @param startSeq the sequence + * @return the builder + */ public T startSeq(long startSeq) { this.startSeq = startSeq; return getThis(); } + /** + * Set the start time + * @param startTime the start time + * @return the builder + */ public T startTime(ZonedDateTime startTime) { this.startTime = startTime; return getThis(); } + /** + * Set the filter subject + * @param filterSubject the filter subject + * @return the builder + */ public T filterSubject(String filterSubject) { this.filterSubject = filterSubject; return getThis(); } + /** + * Set the external reference + * @param external the external + * @return the builder + */ public T external(External external) { this.external = external; return getThis(); } + /** + * Set the domain + * @param domain the domain + * @return the builder + */ public T domain(String domain) { String prefix = convertDomainToPrefix(domain); external = prefix == null ? null : External.builder().api(prefix).build(); return getThis(); } + /** + * Set subjectTransforms + * @param subjectTransforms the array of subjectTransforms + * @return the builder + */ public T subjectTransforms(SubjectTransform... subjectTransforms) { if (nullOrEmpty(subjectTransforms)) { this.subjectTransforms = null; @@ -189,6 +263,11 @@ public T subjectTransforms(SubjectTransform... subjectTransforms) { return _subjectTransforms(Arrays.asList(subjectTransforms)); } + /** + * Set subjectTransforms + * @param subjectTransforms the list of subjectTransforms + * @return the builder + */ public T subjectTransforms(List subjectTransforms) { if (nullOrEmpty(subjectTransforms)) { this.subjectTransforms = null; diff --git a/src/main/java/io/nats/client/api/StorageType.java b/src/main/java/io/nats/client/api/StorageType.java index bdbbb28fd..8546b0857 100644 --- a/src/main/java/io/nats/client/api/StorageType.java +++ b/src/main/java/io/nats/client/api/StorageType.java @@ -19,7 +19,9 @@ * Stream storage types. */ public enum StorageType { + /** File Storage */ File("file"), + /** Memory Storage */ Memory("memory"); private final String policy; @@ -33,6 +35,11 @@ public String toString() { return policy; } + /** + * Get an instance from the JSON value + * @param value the value + * @return the instance or null if the string is not matched + */ @Nullable public static StorageType get(String value) { if (File.policy.equalsIgnoreCase(value)) { return File; } diff --git a/src/main/java/io/nats/client/api/StreamAlternate.java b/src/main/java/io/nats/client/api/StreamAlternate.java index 5c5140667..d4b9f8a7a 100644 --- a/src/main/java/io/nats/client/api/StreamAlternate.java +++ b/src/main/java/io/nats/client/api/StreamAlternate.java @@ -23,6 +23,9 @@ import static io.nats.client.support.ApiConstants.*; import static io.nats.client.support.JsonValueUtils.readString; +/** + * The Stream Alternate + */ public class StreamAlternate { private final String name; private final String domain; diff --git a/src/main/java/io/nats/client/api/StreamConfiguration.java b/src/main/java/io/nats/client/api/StreamConfiguration.java index fe5c3952b..e807398b0 100644 --- a/src/main/java/io/nats/client/api/StreamConfiguration.java +++ b/src/main/java/io/nats/client/api/StreamConfiguration.java @@ -167,7 +167,7 @@ static StreamConfiguration instance(JsonValue v) { * @see #toJson() * @param json the json representing the Stream Configuration * @return StreamConfiguration for the given json - * @throws JsonParseException thrown if the parsing fails for invalid json + * @throws JsonParseException if there is a problem parsing the json */ public static StreamConfiguration instance(String json) throws JsonParseException { return instance(JsonParser.parse(json)); diff --git a/src/main/java/io/nats/client/api/StreamInfo.java b/src/main/java/io/nats/client/api/StreamInfo.java index 85038ee71..3bf5c4270 100644 --- a/src/main/java/io/nats/client/api/StreamInfo.java +++ b/src/main/java/io/nats/client/api/StreamInfo.java @@ -42,10 +42,18 @@ public class StreamInfo extends ApiResponse { private final List alternates; private final ZonedDateTime timestamp; + /** + * Construct a StreamInfo instance from a message + * @param msg the message + */ public StreamInfo(@NonNull Message msg) { this(parseUnchecked(msg.getData())); } + /** + * Construct a StreamInfo instance from a JsonValue + * @param vStreamInfo the JsonValue + */ public StreamInfo(@NonNull JsonValue vStreamInfo) { super(vStreamInfo); if (hasError()) { @@ -111,21 +119,37 @@ public ZonedDateTime getCreateTime() { return createTime; } + /** + * Gets the mirror info + * @return the mirror info + */ @Nullable public MirrorInfo getMirrorInfo() { return mirrorInfo; } + /** + * Gets the source info + * @return the source info + */ @Nullable public List getSourceInfos() { return sourceInfos; } + /** + * Gets the cluster info + * @return the cluster info + */ @Nullable public ClusterInfo getClusterInfo() { return clusterInfo; } + /** + * Gets the stream alternates + * @return the stream alternates + */ @Nullable public List getAlternates() { return alternates; diff --git a/src/main/java/io/nats/client/api/StreamInfoOptions.java b/src/main/java/io/nats/client/api/StreamInfoOptions.java index ce94f740d..5b551367d 100644 --- a/src/main/java/io/nats/client/api/StreamInfoOptions.java +++ b/src/main/java/io/nats/client/api/StreamInfoOptions.java @@ -35,11 +35,19 @@ private StreamInfoOptions(String subjectsFilter, boolean deletedDetails) { this.deletedDetails = deletedDetails; } + /** + * Get the configured subject filter + * @return the subject filter + */ @Nullable public String getSubjectsFilter() { return subjectsFilter; } + /** + * Get the configured flag requesting deleted details + * @return true if configured for deleted details + */ public boolean isDeletedDetails() { return deletedDetails; } @@ -69,6 +77,10 @@ public static StreamInfoOptions deletedDetails() { return new Builder().deletedDetails().build(); } + /** + * Get an instance of the builder + * @return the builder + */ public static Builder builder() { return new Builder(); } @@ -94,7 +106,7 @@ public static class Builder { private boolean deletedDetails; /** - * Default Builder + * Construct an instance of the builder */ public Builder() {} diff --git a/src/main/java/io/nats/client/api/StreamState.java b/src/main/java/io/nats/client/api/StreamState.java index 93b038fde..9ef7c135d 100644 --- a/src/main/java/io/nats/client/api/StreamState.java +++ b/src/main/java/io/nats/client/api/StreamState.java @@ -26,6 +26,9 @@ import static io.nats.client.support.ApiConstants.*; import static io.nats.client.support.JsonValueUtils.*; +/** + * Object representing the state of a stream + */ public class StreamState { private final long msgs; private final long bytes; diff --git a/src/main/java/io/nats/client/api/Subject.java b/src/main/java/io/nats/client/api/Subject.java index 61f6e1214..d1b18d2fd 100644 --- a/src/main/java/io/nats/client/api/Subject.java +++ b/src/main/java/io/nats/client/api/Subject.java @@ -21,6 +21,9 @@ import static io.nats.client.support.JsonValueUtils.getLong; +/** + * An object representing a stream's subject and the count of it's messages + */ public class Subject implements Comparable { private final String name; private final long count; @@ -38,6 +41,11 @@ static List listOf(JsonValue vSubjects) { return list; } + /** + * Construct a Subject instance + * @param name the subject name + * @param count the message count + */ public Subject(String name, long count) { this.name = name; this.count = count; diff --git a/src/main/java/io/nats/client/api/SubjectTransform.java b/src/main/java/io/nats/client/api/SubjectTransform.java index aebbb35d4..377713c90 100644 --- a/src/main/java/io/nats/client/api/SubjectTransform.java +++ b/src/main/java/io/nats/client/api/SubjectTransform.java @@ -99,6 +99,11 @@ public static class Builder { private String source; private String destination; + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * Set the Published Subject-matching filter * @param source the source diff --git a/src/main/java/io/nats/client/api/SuccessApiResponse.java b/src/main/java/io/nats/client/api/SuccessApiResponse.java index 8459a98d6..fa025bfb5 100644 --- a/src/main/java/io/nats/client/api/SuccessApiResponse.java +++ b/src/main/java/io/nats/client/api/SuccessApiResponse.java @@ -18,9 +18,16 @@ import static io.nats.client.support.ApiConstants.SUCCESS; import static io.nats.client.support.JsonValueUtils.readBoolean; +/** + * A response indicating a successful api call + */ public class SuccessApiResponse extends ApiResponse { boolean success; + /** + * Construct a SuccessApiResponse from a message + * @param msg the message + */ public SuccessApiResponse(Message msg) { super(msg); Boolean b = readBoolean(jv, SUCCESS, null); @@ -32,6 +39,10 @@ public SuccessApiResponse(Message msg) { } } + /** + * Get the success state + * @return true if the call was successful + */ public boolean getSuccess() { return success; } diff --git a/src/main/java/io/nats/client/api/Watcher.java b/src/main/java/io/nats/client/api/Watcher.java index f0c33e49a..7c2803304 100644 --- a/src/main/java/io/nats/client/api/Watcher.java +++ b/src/main/java/io/nats/client/api/Watcher.java @@ -17,6 +17,7 @@ /** * Use the Watcher interface to watch for updates + * @param the type being watched */ public interface Watcher { diff --git a/src/main/java/io/nats/client/impl/ReaderListenerConsoleImpl.java b/src/main/java/io/nats/client/impl/ReaderListenerConsoleImpl.java index c4770d0e1..fb6d88e56 100644 --- a/src/main/java/io/nats/client/impl/ReaderListenerConsoleImpl.java +++ b/src/main/java/io/nats/client/impl/ReaderListenerConsoleImpl.java @@ -18,8 +18,8 @@ public class ReaderListenerConsoleImpl implements ReadListener { @Override - public void protocol(String op, String string) { - System.out.println("RL/Protocol " + op + " " + string); + public void protocol(String op, String text) { + System.out.println("RL/Protocol " + op + " " + text); } @Override diff --git a/src/main/java/io/nats/client/support/ApiConstants.java b/src/main/java/io/nats/client/support/ApiConstants.java index 4cf05bf4b..d2e5f7cc9 100644 --- a/src/main/java/io/nats/client/support/ApiConstants.java +++ b/src/main/java/io/nats/client/support/ApiConstants.java @@ -13,224 +13,231 @@ package io.nats.client.support; +/** + * Constants covering server api schema fields + */ public interface ApiConstants { + /** ack_floor */ String ACK_FLOOR = "ack_floor"; + /** ack_policy */ String ACK_POLICY = "ack_policy"; + /** ack_wait */ String ACK_WAIT = "ack_wait"; + /** action */ String ACTION = "action"; + /** active */ String ACTIVE = "active"; + /** allow_atomic */ String ALLOW_ATOMIC = "allow_atomic"; + /** allow_direct */ String ALLOW_DIRECT = "allow_direct"; + /** allow_msg_schedules */ String ALLOW_MSG_SCHEDULES = "allow_msg_schedules"; + /** allow_msg_counter */ String ALLOW_MSG_COUNTER = "allow_msg_counter"; + /** allow_msg_ttl */ String ALLOW_MSG_TTL = "allow_msg_ttl"; + /** allow_rollup_hdrs */ String ALLOW_ROLLUP_HDRS = "allow_rollup_hdrs"; + /** alternates */ String ALTERNATES = "alternates"; + /** api */ String API = "api"; + /** api_url */ String API_URL = "api_url"; + /** auth_required */ String AUTH_REQUIRED = "auth_required"; + /** average_processing_time */ String AVERAGE_PROCESSING_TIME = "average_processing_time"; + /** backoff */ String BACKOFF = "backoff"; + /** batch */ String BATCH = "batch"; + /** bucket */ String BUCKET = "bucket"; + /** bytes */ String BYTES = "bytes"; + /** chunks */ String CHUNKS = "chunks"; + /** client_id */ String CLIENT_ID = "client_id"; + /** client_ip */ String CLIENT_IP = "client_ip"; + /** cluster */ String CLUSTER = "cluster"; + /** code */ String CODE = "code"; + /** compression */ String COMPRESSION = "compression"; + /** config */ String CONFIG = "config"; + /** connect_urls */ String CONNECT_URLS = "connect_urls"; + /** consumer_count */ String CONSUMER_COUNT = "consumer_count"; + /** consumer_seq */ String CONSUMER_SEQ = "consumer_seq"; + /** consumer_limits */ String CONSUMER_LIMITS = "consumer_limits"; + /** consumers */ String CONSUMERS = "consumers"; + /** count */ String COUNT = "count"; + /** created */ String CREATED = "created"; + /** current */ String CURRENT = "current"; + /** data */ String DATA = "data"; + /** deleted */ String DELETED = "deleted"; + /** deleted_details */ String DELETED_DETAILS = "deleted_details"; + /** deliver */ String DELIVER = "deliver"; + /** deliver_group */ String DELIVER_GROUP = "deliver_group"; + /** deliver_policy */ String DELIVER_POLICY = "deliver_policy"; + /** deliver_subject */ String DELIVER_SUBJECT = "deliver_subject"; + /** delivered */ String DELIVERED = "delivered"; + /** deny_delete */ String DENY_DELETE = "deny_delete"; + /** deny_purge */ String DENY_PURGE = "deny_purge"; + /** description */ String DESCRIPTION = "description"; + /** dest */ String DEST = "dest"; + /** digest */ String DIGEST = "digest"; + /** discard */ String DISCARD = "discard"; + /** discard_new_per_subject */ String DISCARD_NEW_PER_SUBJECT = "discard_new_per_subject"; + /** domain */ String DOMAIN = "domain"; + /** duplicate */ String DUPLICATE = "duplicate"; + /** duplicate_window */ String DUPLICATE_WINDOW = "duplicate_window"; + /** endpoints */ String ENDPOINTS = "endpoints"; + /** durable_name */ String DURABLE_NAME = "durable_name"; + /** err_code */ String ERR_CODE = "err_code"; + /** error */ String ERROR = "error"; + /** errors */ String ERRORS = "errors"; + /** expires */ String EXPIRES = "expires"; + /** expires_in */ String EXPIRES_IN = "expires_in"; + /** external */ String EXTERNAL = "external"; + /** filter */ String FILTER = "filter"; + /** filter_subject */ String FILTER_SUBJECT = "filter_subject"; + /** filter_subjects */ String FILTER_SUBJECTS = "filter_subjects"; + /** first_seq */ String FIRST_SEQ = "first_seq"; + /** first_ts */ String FIRST_TS = "first_ts"; + /** flow_control */ String FLOW_CONTROL = "flow_control"; + /** go */ String GO = "go"; + /** group */ String GROUP = "group"; + /** hdrs */ String HDRS = "hdrs"; + /** headers */ String HEADERS = "headers"; + /** headers_only */ String HEADERS_ONLY = "headers_only"; + /** host */ String HOST = "host"; + /** id */ String ID = "id"; + /** idle_heartbeat */ String IDLE_HEARTBEAT = "idle_heartbeat"; + /** inactive_threshold */ String INACTIVE_THRESHOLD = "inactive_threshold"; + /** inflight */ String INFLIGHT = "inflight"; + /** internal */ String INTERNAL = "internal"; + /** jetstream */ String JETSTREAM = "jetstream"; + /** keep */ String KEEP = "keep"; + /** lag */ String LAG = "lag"; + /** ldm */ String LAME_DUCK_MODE = "ldm"; + /** last_active */ String LAST_ACTIVE = "last_active"; + /** last_by_subj */ String LAST_BY_SUBJECT = "last_by_subj"; + /** last_error */ String LAST_ERROR = "last_error"; + /** last_seq */ String LAST_SEQ = "last_seq"; + /** last_ts */ String LAST_TS = "last_ts"; + /** leader */ String LEADER = "leader"; + /** leader_since */ String LEADER_SINCE = "leader_since"; + /** level */ String LEVEL = "level"; + /** limit */ String LIMIT = "limit"; + /** limits */ String LIMITS = "limits"; + /** link */ String LINK = "link"; + /** lost */ String LOST = "lost"; + /** max_ack_pending */ String MAX_ACK_PENDING = "max_ack_pending"; + /** max_age */ String MAX_AGE = "max_age"; + /** max_batch */ String MAX_BATCH = "max_batch"; + /** max_bytes */ String MAX_BYTES = "max_bytes"; + /** max_bytes_required */ String MAX_BYTES_REQUIRED = "max_bytes_required"; + /** max_consumers */ String MAX_CONSUMERS = "max_consumers"; + /** max_chunk_size */ String MAX_CHUNK_SIZE = "max_chunk_size"; + /** max_deliver */ String MAX_DELIVER = "max_deliver"; + /** max_expires */ String MAX_EXPIRES = "max_expires"; + /** max_memory */ String MAX_MEMORY = "max_memory"; + /** max_msg_size */ String MAX_MSG_SIZE = "max_msg_size"; + /** max_msgs */ String MAX_MSGS = "max_msgs"; + /** max_msgs_per_subject */ String MAX_MSGS_PER_SUB = "max_msgs_per_subject"; + /** max_payload */ String MAX_PAYLOAD = "max_payload"; + /** max_storage */ String MAX_STORAGE = "max_storage"; + /** max_streams */ String MAX_STREAMS = "max_streams"; + /** max_waiting */ String MAX_WAITING = "max_waiting"; // this is correct! the meaning name is different than the field name + /** min_pending */ String MIN_PENDING = "min_pending"; + /** min_ack_pending */ String MIN_ACK_PENDING = "min_ack_pending"; + /** mem_storage */ String MEM_STORAGE = "mem_storage"; + /** memory */ String MEMORY = "memory"; + /** memory_max_stream_bytes */ String MEMORY_MAX_STREAM_BYTES = "memory_max_stream_bytes"; + /** message */ String MESSAGE = "message"; + /** messages */ String MESSAGES = "messages"; + /** metadata */ String METADATA = "metadata"; + /** mtime */ String MTIME = "mtime"; + /** mirror */ String MIRROR = "mirror"; + /** mirror_direct */ String MIRROR_DIRECT = "mirror_direct"; + /** msgs */ String MSGS = "msgs"; + /** multi_last */ String MULTI_LAST = "multi_last"; + /** name */ String NAME = "name"; + /** next_by_subj */ String NEXT_BY_SUBJECT = "next_by_subj"; + /** no_ack */ String NO_ACK = "no_ack"; + /** no_erase */ String NO_ERASE = "no_erase"; + /** no_wait */ String NO_WAIT = "no_wait"; + /** nonce */ String NONCE = "nonce"; + /** nuid */ String NUID = "nuid"; + /** num_ack_pending */ String NUM_ACK_PENDING = "num_ack_pending"; + /** num_deleted */ String NUM_DELETED = "num_deleted"; + /** num_errors */ String NUM_ERRORS = "num_errors"; + /** num_pending */ String NUM_PENDING = "num_pending"; + /** num_redelivered */ String NUM_REDELIVERED = "num_redelivered"; + /** num_replicas */ String NUM_REPLICAS = "num_replicas"; + /** num_requests */ String NUM_REQUESTS = "num_requests"; + /** num_subjects */ String NUM_SUBJECTS = "num_subjects"; + /** num_waiting */ String NUM_WAITING = "num_waiting"; + /** offline */ String OFFLINE = "offline"; + /** offset */ String OFFSET = "offset"; + /** opt_start_seq */ String OPT_START_SEQ = "opt_start_seq"; + /** opt_start_time */ String OPT_START_TIME = "opt_start_time"; + /** options */ String OPTIONS = "options"; + /** paused */ String PAUSED = "paused"; + /** pause_remaining */ String PAUSE_REMAINING = "pause_remaining"; + /** pause_until */ String PAUSE_UNTIL = "pause_until"; + /** persist_mode */ String PERSIST_MODE = "persist_mode"; + /** pinned_client_id */ String PINNED_CLIENT_ID = "pinned_client_id"; + /** pinned_ts */ String PINNED_TS = "pinned_ts"; + /** placement */ String PLACEMENT = "placement"; + /** port */ String PORT = "port"; + /** priority */ String PRIORITY = "priority"; + /** priority_groups */ String PRIORITY_GROUPS = "priority_groups"; + /** priority_policy */ String PRIORITY_POLICY = "priority_policy"; + /** priority_timeout */ String PRIORITY_TIMEOUT = "priority_timeout"; + /** processing_time */ String PROCESSING_TIME = "processing_time"; + /** proto */ String PROTO = "proto"; + /** purged */ String PURGED = "purged"; + /** push_bound */ String PUSH_BOUND = "push_bound"; + /** queue_group */ String QUEUE_GROUP = "queue_group"; + /** raft_group */ String RAFT_GROUP = "raft_group"; + /** raise_status_warnings */ String RAISE_STATUS_WARNINGS = "raise_status_warnings"; + /** rate_limit_bps */ String RATE_LIMIT_BPS = "rate_limit_bps"; + /** replay_policy */ String REPLAY_POLICY = "replay_policy"; + /** replica */ String REPLICA = "replica"; + /** replicas */ String REPLICAS = "replicas"; + /** republish */ String REPUBLISH = "republish"; + /** request */ String REQUEST = "request"; + /** reserved_memory */ String RESERVED_MEMORY = "reserved_memory"; + /** reserved_storage */ String RESERVED_STORAGE = "reserved_storage"; + /** response */ String RESPONSE = "response"; + /** retention */ String RETENTION = "retention"; + /** sample_freq */ String SAMPLE_FREQ = "sample_freq"; + /** schema */ String SCHEMA = "schema"; + /** sealed */ String SEALED = "sealed"; + /** seq */ String SEQ = "seq"; + /** server_id */ String SERVER_ID = "server_id"; + /** server_name */ String SERVER_NAME = "server_name"; + /** size */ String SIZE = "size"; + /** source */ String SOURCE = "source"; + /** sources */ String SOURCES = "sources"; + /** src */ String SRC = "src"; + /** started */ String STARTED = "started"; + /** start_time */ String START_TIME = "start_time"; + /** state */ String STATE = "state"; + /** stats */ String STATS = "stats"; + /** storage */ String STORAGE = "storage"; + /** storage_max_stream_bytes */ String STORAGE_MAX_STREAM_BYTES = "storage_max_stream_bytes"; + /** stream_name */ String STREAM_NAME = "stream_name"; + /** stream_seq */ String STREAM_SEQ = "stream_seq"; + /** stream */ String STREAM = "stream"; + /** streams */ String STREAMS = "streams"; + /** subject */ String SUBJECT = "subject"; + /** subject_delete_marker_ttl */ String SUBJECT_DELETE_MARKER_TTL = "subject_delete_marker_ttl"; + /** subject_transform */ String SUBJECT_TRANSFORM = "subject_transform"; + /** subject_transforms */ String SUBJECT_TRANSFORMS = "subject_transforms"; + /** subjects */ String SUBJECTS = "subjects"; + /** subjects_filter */ String SUBJECTS_FILTER = "subjects_filter"; + /** success */ String SUCCESS = "success"; + /** system_account */ String SYSTEM_ACCOUNT = "system_account"; + /** tags */ String TAGS = "tags"; + /** template_owner */ String TEMPLATE_OWNER = "template_owner"; + /** threshold_percent */ String THRESHOLD_PERCENT = "threshold_percent"; + /** tiers */ String TIERS = "tiers"; + /** time */ String TIME = "time"; + /** ts */ String TIMESTAMP = "ts"; + /** tls_required */ String TLS_REQUIRED = "tls_required"; + /** tls_available */ String TLS_AVAILABLE = "tls_available"; + /** total */ String TOTAL = "total"; + /** traffic_account */ String TRAFFIC_ACCOUNT = "traffic_account"; + /** type */ String TYPE = "type"; + /** up_to_seq */ String UP_TO_SEQ = "up_to_seq"; + /** up_to_time */ String UP_TO_TIME = "up_to_time"; + /** val */ String VAL = "val"; + /** version */ String VERSION = "version"; - String ACK_FLOOR = "ack_floor"; - String ACK_POLICY = "ack_policy"; - String ACK_WAIT = "ack_wait"; - String ACTION = "action"; - String ACTIVE = "active"; - String ALLOW_ATOMIC = "allow_atomic"; - String ALLOW_DIRECT = "allow_direct"; - String ALLOW_MSG_SCHEDULES = "allow_msg_schedules"; - String ALLOW_MSG_COUNTER = "allow_msg_counter"; - String ALLOW_MSG_TTL = "allow_msg_ttl"; - String ALLOW_ROLLUP_HDRS = "allow_rollup_hdrs"; - String ALTERNATES = "alternates"; - String API = "api"; - String API_URL = "api_url"; - String AUTH_REQUIRED = "auth_required"; - String AVERAGE_PROCESSING_TIME = "average_processing_time"; - String BACKOFF = "backoff"; - String BATCH = "batch"; - String BUCKET = "bucket"; - String BYTES = "bytes"; - String CHUNKS = "chunks"; - String CLIENT_ID = "client_id"; - String CLIENT_IP = "client_ip"; - String CLUSTER = "cluster"; - String CODE = "code"; - String COMPRESSION = "compression"; - String CONFIG = "config"; - String CONNECT_URLS = "connect_urls"; - String CONSUMER_COUNT = "consumer_count"; - String CONSUMER_SEQ = "consumer_seq"; - String CONSUMER_LIMITS = "consumer_limits"; - String CONSUMERS = "consumers"; - String COUNT = "count"; - String CREATED = "created"; - String CURRENT = "current"; - String DATA = "data"; - String DELETED = "deleted"; - String DELETED_DETAILS = "deleted_details"; - String DELIVER = "deliver"; - String DELIVER_GROUP = "deliver_group"; - String DELIVER_POLICY = "deliver_policy"; - String DELIVER_SUBJECT = "deliver_subject"; - String DELIVERED = "delivered"; - String DENY_DELETE = "deny_delete"; - String DENY_PURGE = "deny_purge"; - String DESCRIPTION = "description"; - String DEST = "dest"; - String DIGEST = "digest"; - String DISCARD = "discard"; - String DISCARD_NEW_PER_SUBJECT = "discard_new_per_subject"; - String DOMAIN = "domain"; - String DUPLICATE = "duplicate"; - String DUPLICATE_WINDOW = "duplicate_window"; - String ENDPOINTS = "endpoints"; - String DURABLE_NAME = "durable_name"; - String ERR_CODE = "err_code"; - String ERROR = "error"; - String ERRORS = "errors"; - String EXPIRES = "expires"; - String EXPIRES_IN = "expires_in"; - String EXTERNAL = "external"; - String FILTER = "filter"; - String FILTER_SUBJECT = "filter_subject"; - String FILTER_SUBJECTS = "filter_subjects"; - String FIRST_SEQ = "first_seq"; - String FIRST_TS = "first_ts"; - String FLOW_CONTROL = "flow_control"; - String GO = "go"; - String GROUP = "group"; - String HDRS = "hdrs"; - String HEADERS = "headers"; - String HEADERS_ONLY = "headers_only"; - String HOST = "host"; - String ID = "id"; - String IDLE_HEARTBEAT = "idle_heartbeat"; - String INACTIVE_THRESHOLD= "inactive_threshold"; - String INFLIGHT = "inflight"; - String INTERNAL = "internal"; - String JETSTREAM = "jetstream"; - String KEEP = "keep"; - String LAG = "lag"; - String LAME_DUCK_MODE = "ldm"; - String LAST_ACTIVE = "last_active"; - String LAST_BY_SUBJECT = "last_by_subj"; - String LAST_ERROR = "last_error"; - String LAST_SEQ = "last_seq"; - String LAST_TS = "last_ts"; - String LEADER = "leader"; - String LEADER_SINCE = "leader_since"; - String LEVEL = "level"; - String LIMIT = "limit"; - String LIMITS = "limits"; - String LINK = "link"; - String LOST = "lost"; - String MAX_ACK_PENDING = "max_ack_pending"; - String MAX_AGE = "max_age"; - String MAX_BATCH = "max_batch"; - String MAX_BYTES = "max_bytes"; - String MAX_BYTES_REQUIRED= "max_bytes_required"; - String MAX_CONSUMERS = "max_consumers"; - String MAX_CHUNK_SIZE = "max_chunk_size"; - String MAX_DELIVER = "max_deliver"; - String MAX_EXPIRES = "max_expires"; - String MAX_MEMORY = "max_memory"; - String MAX_MSG_SIZE = "max_msg_size"; - String MAX_MSGS = "max_msgs"; - String MAX_MSGS_PER_SUB = "max_msgs_per_subject"; - String MAX_PAYLOAD = "max_payload"; - String MAX_STORAGE = "max_storage"; - String MAX_STREAMS = "max_streams"; - String MAX_WAITING = "max_waiting"; // this is correct! the meaning name is different than the field name - String MIN_PENDING = "min_pending"; - String MIN_ACK_PENDING = "min_ack_pending"; - String MEM_STORAGE = "mem_storage"; - String MEMORY = "memory"; - String MEMORY_MAX_STREAM_BYTES = "memory_max_stream_bytes"; - String MESSAGE = "message"; - String MESSAGES = "messages"; - String METADATA = "metadata"; - String MTIME = "mtime"; - String MIRROR = "mirror"; - String MIRROR_DIRECT = "mirror_direct"; - String MSGS = "msgs"; - String MULTI_LAST = "multi_last"; - String NAME = "name"; - String NEXT_BY_SUBJECT = "next_by_subj"; - String NO_ACK = "no_ack"; - String NO_ERASE = "no_erase"; - String NO_WAIT = "no_wait"; - String NONCE = "nonce"; - String NUID = "nuid"; - String NUM_ACK_PENDING = "num_ack_pending"; - String NUM_DELETED = "num_deleted"; - String NUM_ERRORS = "num_errors"; - String NUM_PENDING = "num_pending"; - String NUM_REDELIVERED = "num_redelivered"; - String NUM_REPLICAS = "num_replicas"; - String NUM_REQUESTS = "num_requests"; - String NUM_SUBJECTS = "num_subjects"; - String NUM_WAITING = "num_waiting"; - String OFFLINE = "offline"; - String OFFSET = "offset"; - String OPT_START_SEQ = "opt_start_seq"; - String OPT_START_TIME = "opt_start_time"; - String OPTIONS = "options"; - String PAUSED = "paused"; - String PAUSE_REMAINING = "pause_remaining"; - String PAUSE_UNTIL = "pause_until"; - String PERSIST_MODE = "persist_mode"; - String PINNED_CLIENT_ID = "pinned_client_id"; - String PINNED_TS = "pinned_ts"; - String PLACEMENT = "placement"; - String PORT = "port"; - String PRIORITY = "priority"; - String PRIORITY_GROUPS = "priority_groups"; - String PRIORITY_POLICY = "priority_policy"; - String PRIORITY_TIMEOUT = "priority_timeout"; - String PROCESSING_TIME = "processing_time"; - String PROTO = "proto"; - String PURGED = "purged"; - String PUSH_BOUND = "push_bound"; - String QUEUE_GROUP = "queue_group"; - String RAFT_GROUP = "raft_group"; - String RAISE_STATUS_WARNINGS = "raise_status_warnings"; - String RATE_LIMIT_BPS = "rate_limit_bps"; - String REPLAY_POLICY = "replay_policy"; - String REPLICA = "replica"; - String REPLICAS = "replicas"; - String REPUBLISH = "republish"; - String REQUEST = "request"; - String RESERVED_MEMORY = "reserved_memory"; - String RESERVED_STORAGE = "reserved_storage"; - String RESPONSE = "response"; - String RETENTION = "retention"; - String SAMPLE_FREQ = "sample_freq"; - String SCHEMA = "schema"; - String SEALED = "sealed"; - String SEQ = "seq"; - String SERVER_ID = "server_id"; - String SERVER_NAME = "server_name"; - String SIZE = "size"; - String SOURCE = "source"; - String SOURCES = "sources"; - String SRC = "src"; - String STARTED = "started"; - String START_TIME = "start_time"; - String STATE = "state"; - String STATS = "stats"; - String STORAGE = "storage"; - String STORAGE_MAX_STREAM_BYTES = "storage_max_stream_bytes"; - String STREAM_NAME = "stream_name"; - String STREAM_SEQ = "stream_seq"; - String STREAM = "stream"; - String STREAMS = "streams"; - String SUBJECT = "subject"; - String SUBJECT_DELETE_MARKER_TTL = "subject_delete_marker_ttl"; - String SUBJECT_TRANSFORM = "subject_transform"; - String SUBJECT_TRANSFORMS = "subject_transforms"; - String SUBJECTS = "subjects"; - String SUBJECTS_FILTER = "subjects_filter"; - String SUCCESS = "success"; - String SYSTEM_ACCOUNT = "system_account"; - String TAGS = "tags"; - String TEMPLATE_OWNER = "template_owner"; - String THRESHOLD_PERCENT = "threshold_percent"; - String TIERS = "tiers"; - String TIME = "time"; - String TIMESTAMP = "ts"; - String TLS = "tls_required"; - String TLS_REQUIRED = TLS; - String TLS_AVAILABLE = "tls_available"; - String TOTAL = "total"; - String TRAFFIC_ACCOUNT = "traffic_account"; - String TYPE = "type"; - String UP_TO_SEQ = "up_to_seq"; - String UP_TO_TIME = "up_to_time"; - String VAL = "val"; - String VERSION = "version"; + /** + * Use TLS_REQUIRED instead + */ + @Deprecated + String TLS = "tls_required"; } diff --git a/src/main/java/io/nats/client/support/BuilderBase.java b/src/main/java/io/nats/client/support/BuilderBase.java index a7a3e2b97..72c6e2cf1 100644 --- a/src/main/java/io/nats/client/support/BuilderBase.java +++ b/src/main/java/io/nats/client/support/BuilderBase.java @@ -18,20 +18,54 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.US_ASCII; +/** + * A base for "builder" classes + */ public abstract class BuilderBase { + /** + * The default character set + */ protected final Charset defaultCharset; + + /** + * The allocation size + */ protected int allocationSize; + /** + * Allocation boundary + */ public static final int ALLOCATION_BOUNDARY = 32; + + /** + * Default allocation for ASCII or ISO_8859_1 charset + */ public static final int DEFAULT_ASCII_ALLOCATION = 32; + + /** + * Default allocation for other charsets + */ public static final int DEFAULT_OTHER_ALLOCATION = 64; + + /** + * a byte array representing the word "null" + */ public static final byte[] NULL = "null".getBytes(ISO_8859_1); + /** + * Construct a builder base + * @param defaultCharset the character set to use as default + * @param allocationSize the allocation size + */ protected BuilderBase(Charset defaultCharset, int allocationSize) { this.defaultCharset = defaultCharset; _setAllocationSize(allocationSize); } + /** + * Internal delegate method to set the allocationSizeSuggestion + * @param allocationSizeSuggestion the suggestion + */ protected void _setAllocationSize(int allocationSizeSuggestion) { int dcas = _defaultCharsetAllocationSize(); if (allocationSizeSuggestion <= dcas) { @@ -109,6 +143,12 @@ private int _defaultCharsetAllocationSize() { return defaultCharset == US_ASCII || defaultCharset == ISO_8859_1 ? DEFAULT_ASCII_ALLOCATION : DEFAULT_OTHER_ALLOCATION; } + /** + * calculate a buffer allocation size + * @param atLeast the allocation must be at least + * @param blockSize the blocksize + * @return the allocation size + */ public static int bufferAllocSize(int atLeast, int blockSize) { return atLeast < blockSize ? blockSize diff --git a/src/main/java/io/nats/client/support/ByteArrayBuilder.java b/src/main/java/io/nats/client/support/ByteArrayBuilder.java index 1d5e3b1a9..4d100e4ca 100644 --- a/src/main/java/io/nats/client/support/ByteArrayBuilder.java +++ b/src/main/java/io/nats/client/support/ByteArrayBuilder.java @@ -22,6 +22,9 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; +/** + * A class that wraps a ByteBuffer that can automatically grow + */ public class ByteArrayBuilder extends BuilderBase { private ByteBuffer buffer; diff --git a/src/main/java/io/nats/client/support/ByteArrayPrimitiveBuilder.java b/src/main/java/io/nats/client/support/ByteArrayPrimitiveBuilder.java index e367989a4..d9944566a 100644 --- a/src/main/java/io/nats/client/support/ByteArrayPrimitiveBuilder.java +++ b/src/main/java/io/nats/client/support/ByteArrayPrimitiveBuilder.java @@ -20,6 +20,9 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; +/** + * A class that wraps a byte array that can automatically grow + */ public class ByteArrayPrimitiveBuilder extends BuilderBase { private byte[] buffer; private int position; diff --git a/src/main/java/io/nats/client/support/Encoding.java b/src/main/java/io/nats/client/support/Encoding.java index c7bb21797..7de5e0ad9 100644 --- a/src/main/java/io/nats/client/support/Encoding.java +++ b/src/main/java/io/nats/client/support/Encoding.java @@ -138,6 +138,12 @@ public static String base64UrlDecodeToString(String input) { private static final int[] BASE32_LOOKUP; private static final int MASK = 31; private static final int SHIFT = 5; + + /** + * base32 encode a byte array + * @param input the input + * @return the encoded character array + */ public static char[] base32Encode(final byte[] input) { int last = input.length; char[] charBuff = new char[(last + 7) * 8 / SHIFT]; @@ -191,6 +197,11 @@ public static char[] base32Encode(final byte[] input) { } } + /** + * base32 decode a character array + * @param input the input + * @return the decoded byte array + */ public static byte[] base32Decode(final char[] input) { byte[] bytes = new byte[input.length * SHIFT / 8]; int buffer = 0; @@ -216,6 +227,11 @@ public static byte[] base32Decode(final char[] input) { return bytes; } + /** + * json decoding of a string + * @param s the string + * @return the decoded string + */ public static String jsonDecode(String s) { int len = s.length(); StringBuilder sb = new StringBuilder(len); @@ -263,10 +279,21 @@ public static String jsonDecode(String s) { return sb.toString(); } + /** + * json encode a string + * @param s the string + * @return the encoded string + */ public static String jsonEncode(String s) { return jsonEncode(new StringBuilder(), s).toString(); } + /** + * json encode a string appended into a StringBuilder + * @param sb the target StringBuilder + * @param s the string + * @return the StringBuilder fluent style + */ public static StringBuilder jsonEncode(StringBuilder sb, String s) { int len = s.length(); for (int x = 0; x < len; x++) { @@ -275,10 +302,21 @@ public static StringBuilder jsonEncode(StringBuilder sb, String s) { return sb; } + /** + * json encode a char array + * @param chars the char array + * @return the encoded string + */ public static String jsonEncode(char[] chars) { return jsonEncode(new StringBuilder(), chars).toString(); } + /** + * json encode a char array appended into a StringBuilder + * @param sb the target StringBuilder + * @param chars the char array + * @return the StringBuilder fluent style + */ public static StringBuilder jsonEncode(StringBuilder sb, char[] chars) { for (char aChar : chars) { appendChar(sb, aChar); @@ -323,6 +361,11 @@ private static void appendChar(StringBuilder sb, char ch) { } } + /** + * perform basic uri decoding, replacing the plus sign with %2B + * @param source the source string + * @return tje decoded string + */ public static String uriDecode(String source) { try { return URLDecoder.decode(source.replace("+", "%2B"), "UTF-8"); diff --git a/src/main/java/io/nats/client/support/HttpRequest.java b/src/main/java/io/nats/client/support/HttpRequest.java index 69da339ca..c614e7d88 100644 --- a/src/main/java/io/nats/client/support/HttpRequest.java +++ b/src/main/java/io/nats/client/support/HttpRequest.java @@ -21,8 +21,7 @@ /** * Encapsulate an HttpRequest, in Java 11 we could use this class: - * https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.html - * + * Java HttpRequest * ...but we want to support older JVMs. */ public class HttpRequest { @@ -32,6 +31,12 @@ public class HttpRequest { private final Headers headers = new Headers(); /** + * construct an HttpRequest + */ + public HttpRequest() {} + + /** + * Get the headers * @return the attached http headers, defaults to GET */ public Headers getHeaders() { @@ -39,7 +44,8 @@ public Headers getHeaders() { } /** - * @return the request method (GET, POST, etc) + * Get the request method + * @return the request method (GET, POST, etc.) */ public String getMethod() { return method; @@ -85,7 +91,8 @@ public HttpRequest uri(String uri) { } /** - * @return the HTTP version to use for this request. Defaults to "1.1" + * the HTTP version to use for this request. Defaults to "1.1" + * @return the version */ public String getVersion() { return version; @@ -94,7 +101,6 @@ public String getVersion() { /** * Note that no validation is performed on the version. Probably only makes * sense to use "0.9", "1.0", "1.1", or "2". - * * @param version is the new HTTP version to use. * @return this for method chaining. */ @@ -107,7 +113,8 @@ public HttpRequest version(String version) { } /** - * @return the textual representation of the HTTP request line + headers (no body) + * the textual representation of the HTTP request line + headers (no body) + * @return the text */ @Override public String toString() { diff --git a/src/main/java/io/nats/client/support/JsonParseException.java b/src/main/java/io/nats/client/support/JsonParseException.java index 2036d46cb..7781d96d8 100644 --- a/src/main/java/io/nats/client/support/JsonParseException.java +++ b/src/main/java/io/nats/client/support/JsonParseException.java @@ -2,15 +2,31 @@ import java.io.IOException; +/** + * An exception when parsing JSON + */ public class JsonParseException extends IOException { + /** + * construct a JsonParseException with message text + * @param message the text + */ public JsonParseException(String message) { super(message); } + /** + * construct a JsonParseException with message text and a cause + * @param message the text + * @param cause the cause + */ public JsonParseException(String message, Throwable cause) { super(message, cause); } + /** + * construct a JsonParseException with a cause + * @param cause the cause + */ public JsonParseException(Throwable cause) { super(cause); } diff --git a/src/main/java/io/nats/client/support/JsonParser.java b/src/main/java/io/nats/client/support/JsonParser.java index 172b14de7..3efa43abb 100644 --- a/src/main/java/io/nats/client/support/JsonParser.java +++ b/src/main/java/io/nats/client/support/JsonParser.java @@ -56,7 +56,7 @@ public enum Option { * Parse JSON from a char array * @param json the JSON * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(char @Nullable [] json) throws JsonParseException { @@ -68,7 +68,7 @@ public static JsonValue parse(char @Nullable [] json) throws JsonParseException * @param json the JSON * @param startIndex the starting index in the array * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(char @Nullable [] json, int startIndex) throws JsonParseException { @@ -80,7 +80,7 @@ public static JsonValue parse(char @Nullable [] json, int startIndex) throws Jso * @param json the JSON * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(char @Nullable [] json, @Nullable Option... options) throws JsonParseException { @@ -93,7 +93,7 @@ public static JsonValue parse(char @Nullable [] json, @Nullable Option... option * @param startIndex the starting index in the array * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(char @Nullable [] json, int startIndex, @Nullable Option... options) throws JsonParseException { @@ -105,7 +105,7 @@ public static JsonValue parse(char @Nullable [] json, int startIndex, @Nullable * Parse JSON from a String * @param json the JSON * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(String json) throws JsonParseException { @@ -118,7 +118,7 @@ public static JsonValue parse(String json) throws JsonParseException { * @param json the JSON * @param startIndex the starting index in the string * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(String json, int startIndex) throws JsonParseException { @@ -130,7 +130,7 @@ public static JsonValue parse(String json, int startIndex) throws JsonParseExcep * @param json the JSON * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(String json, @Nullable Option... options) throws JsonParseException { @@ -143,7 +143,7 @@ public static JsonValue parse(String json, @Nullable Option... options) throws J * @param startIndex the starting index in the array * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(String json, int startIndex, @Nullable Option... options) throws JsonParseException { @@ -154,7 +154,7 @@ public static JsonValue parse(String json, int startIndex, @Nullable Option... o * Parse JSON from a byte array * @param json the JSON * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(byte[] json) throws JsonParseException { @@ -166,7 +166,7 @@ public static JsonValue parse(byte[] json) throws JsonParseException { * @param json the JSON * @param startIndex the starting index in the array * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(byte[] json, int startIndex) throws JsonParseException { @@ -178,7 +178,7 @@ public static JsonValue parse(byte[] json, int startIndex) throws JsonParseExcep * @param json the JSON * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(byte[] json, @Nullable Option... options) throws JsonParseException { @@ -191,7 +191,7 @@ public static JsonValue parse(byte[] json, @Nullable Option... options) throws J * @param startIndex the starting index in the array * @param options options for how to parse * @return the JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public static JsonValue parse(byte[] json, int startIndex, @Nullable Option... options) throws JsonParseException { @@ -411,7 +411,7 @@ public JsonParser(char @Nullable [] json, int startIndex, @Nullable Option... op /** * Parse the JSON * @return a JsonValue - * @throws JsonParseException if there is a problem parsing + * @throws JsonParseException if there is a problem parsing the json */ @NonNull public JsonValue parse() throws JsonParseException { diff --git a/src/main/java/io/nats/client/support/JsonSerializable.java b/src/main/java/io/nats/client/support/JsonSerializable.java index 55a46e19a..581f14605 100644 --- a/src/main/java/io/nats/client/support/JsonSerializable.java +++ b/src/main/java/io/nats/client/support/JsonSerializable.java @@ -17,14 +17,29 @@ import java.nio.charset.StandardCharsets; +/** + * A general interface for an object to be able to converted to JSON + */ public interface JsonSerializable { + /** + * Get the JSON string + * @return the string + */ @NonNull String toJson(); + /** + * Get the JSON string as a byte array + * @return the byte array + */ default byte @NonNull [] serialize() { return toJson().getBytes(StandardCharsets.UTF_8); } + /** + * Get the JsonValue for the object + * @return the value + */ @NonNull default JsonValue toJsonValue() { return JsonParser.parseUnchecked(toJson()); diff --git a/src/main/java/io/nats/client/support/JwtUtils.java b/src/main/java/io/nats/client/support/JwtUtils.java index a905df7fb..a762f8b2d 100644 --- a/src/main/java/io/nats/client/support/JwtUtils.java +++ b/src/main/java/io/nats/client/support/JwtUtils.java @@ -141,6 +141,20 @@ public static String issueUserJWT(NKey signingKey, String accountId, String publ return issueUserJWT(signingKey, publicUserKey, name, expiration, issuedAt, null, new UserClaim(accountId).tags(tags)); } + /** + * Issue a user JWT from a scoped signing key. See Signing Keys + * @param signingKey a mandatory account nkey pair to sign the generated jwt. + * @param accountId a mandatory public account nkey. Will throw error when not set or not account nkey. + * @param publicUserKey a mandatory public user nkey. Will throw error when not set or not user nkey. + * @param name optional human-readable name. When absent, default to publicUserKey. + * @param expiration optional but recommended duration, when the generated jwt needs to expire. If not set, JWT will not expire. + * @param tags optional list of tags to be included in the JWT. + * @param issuedAt the current epoch seconds. + * @param audience the audience value + * @return a JWT + * @throws GeneralSecurityException if SHA-256 MessageDigest is missing, or if the signingKey can not be used for signing. + * @throws IOException if signingKey sign method throws this exception. + */ public static String issueUserJWT(NKey signingKey, String accountId, String publicUserKey, String name, Duration expiration, String[] tags, long issuedAt, String audience) throws GeneralSecurityException, IOException { return issueUserJWT(signingKey, publicUserKey, name, expiration, issuedAt, audience, new UserClaim(accountId).tags(tags)); } diff --git a/src/main/java/io/nats/client/support/NatsInetAddress.java b/src/main/java/io/nats/client/support/NatsInetAddress.java index a7a9a15f6..00495b558 100644 --- a/src/main/java/io/nats/client/support/NatsInetAddress.java +++ b/src/main/java/io/nats/client/support/NatsInetAddress.java @@ -16,6 +16,9 @@ import java.net.InetAddress; import java.net.UnknownHostException; +/** + * Bridge to the NatsInetAddressProvider implementation + */ public final class NatsInetAddress { private static NatsInetAddressProvider PROVIDER = new NatsInetAddressProvider() {}; @@ -29,26 +32,70 @@ public static void setProvider(final NatsInetAddressProvider provider) { PROVIDER = provider == null ? new NatsInetAddressProvider() {} : provider; } + /** + * Creates an InetAddress based on the provided host name and IP address. + * @param host the specified host + * @param addr the raw IP address in network byte order + * @return an InetAddress object created from the raw IP address. + * @throws UnknownHostException if IP address is of illegal length + */ public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException { return PROVIDER.getByAddress(host, addr); } + /** + * Determines the IP address of a host, given the host's name. + * @param host the specified host, or {@code null}. + * @return an IP address for the given host name. + * @throws UnknownHostException if no IP address for the + * {@code host} could be found, or if a scope_id was specified + * for a global IPv6 address. + * @throws SecurityException if a security manager exists + * and its checkConnect method doesn't allow the operation + */ public static InetAddress getByName(String host) throws UnknownHostException { return PROVIDER.getByName(host); } + /** + * Given the name of a host, returns an array of its IP addresses, + * @param host the name of the host, or {@code null}. + * @return an array of all the IP addresses for a given host name. + * + * @throws UnknownHostException if no IP address for the + * {@code host} could be found, or if a scope_id was specified + * for a global IPv6 address. + * @throws SecurityException if a security manager exists and its + * {@code checkConnect} method doesn't allow the operation. + */ public static InetAddress[] getAllByName(String host) throws UnknownHostException { return PROVIDER.getAllByName(host); } + /** + * Returns the loopback address. + * @return the InetAddress loopback instance. + */ public static InetAddress getLoopbackAddress() { return PROVIDER.getLoopbackAddress(); } + /** + * Returns an {@code InetAddress} object given the raw IP address . + * @param addr the raw IP address in network byte order + * @return an InetAddress object created from the raw IP address. + * @throws UnknownHostException if IP address is of illegal length + */ public static InetAddress getByAddress(byte[] addr) throws UnknownHostException { return PROVIDER.getByAddress(addr); } + /** + * Returns the address of the local host. + * @return the address of the local host. + * @throws UnknownHostException if the local host name could not + * be resolved into an address. + */ public static InetAddress getLocalHost() throws UnknownHostException { return PROVIDER.getLocalHost(); } diff --git a/src/main/java/io/nats/client/support/NatsInetAddressProvider.java b/src/main/java/io/nats/client/support/NatsInetAddressProvider.java index 0b1af0126..32ffded36 100644 --- a/src/main/java/io/nats/client/support/NatsInetAddressProvider.java +++ b/src/main/java/io/nats/client/support/NatsInetAddressProvider.java @@ -16,27 +16,74 @@ import java.net.InetAddress; import java.net.UnknownHostException; +/** + * Interface to implement to provide a InetAddress implementation + */ public interface NatsInetAddressProvider { + /** + * Creates an InetAddress based on the provided host name and IP address. + * @param host the specified host + * @param addr the raw IP address in network byte order + * @return an InetAddress object created from the raw IP address. + * @throws UnknownHostException if IP address is of illegal length + */ default InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException { return InetAddress.getByAddress(host, addr); } + /** + * Determines the IP address of a host, given the host's name. + * @param host the specified host, or {@code null}. + * @return an IP address for the given host name. + * @throws UnknownHostException if no IP address for the + * {@code host} could be found, or if a scope_id was specified + * for a global IPv6 address. + * @throws SecurityException if a security manager exists + * and its checkConnect method doesn't allow the operation + */ default InetAddress getByName(String host) throws UnknownHostException { return InetAddress.getByName(host); } + /** + * Given the name of a host, returns an array of its IP addresses, + * @param host the name of the host, or {@code null}. + * @return an array of all the IP addresses for a given host name. + * + * @throws UnknownHostException if no IP address for the + * {@code host} could be found, or if a scope_id was specified + * for a global IPv6 address. + * @throws SecurityException if a security manager exists and its + * {@code checkConnect} method doesn't allow the operation. + */ default InetAddress[] getAllByName(String host) throws UnknownHostException { return InetAddress.getAllByName(host); } + /** + * Returns the loopback address. + * @return the InetAddress loopback instance. + */ default InetAddress getLoopbackAddress() { return InetAddress.getLoopbackAddress(); } + /** + * Returns an {@code InetAddress} object given the raw IP address . + * @param addr the raw IP address in network byte order + * @return an InetAddress object created from the raw IP address. + * @throws UnknownHostException if IP address is of illegal length + */ default InetAddress getByAddress(byte[] addr) throws UnknownHostException { return InetAddress.getByAddress(addr); } + /** + * Returns the address of the local host. + * @return the address of the local host. + * @throws UnknownHostException if the local host name could not + * be resolved into an address. + */ default InetAddress getLocalHost() throws UnknownHostException { return InetAddress.getLocalHost(); } diff --git a/src/main/java/io/nats/service/Discovery.java b/src/main/java/io/nats/service/Discovery.java index 5c28dcf59..80a9d4173 100644 --- a/src/main/java/io/nats/service/Discovery.java +++ b/src/main/java/io/nats/service/Discovery.java @@ -36,7 +36,9 @@ *

'maxResults' defaults tp {@value DEFAULT_DISCOVERY_MAX_RESULTS}

*/ public class Discovery { + /** Default discover time */ public static final long DEFAULT_DISCOVERY_MAX_TIME_MILLIS = 5000; + /** Default discoverer max results */ public static final int DEFAULT_DISCOVERY_MAX_RESULTS = 10; private final Connection conn; diff --git a/src/main/java/io/nats/service/Endpoint.java b/src/main/java/io/nats/service/Endpoint.java index d36f66143..e51e8298d 100644 --- a/src/main/java/io/nats/service/Endpoint.java +++ b/src/main/java/io/nats/service/Endpoint.java @@ -38,6 +38,9 @@ *

*/ public class Endpoint implements JsonSerializable { + /** + * The name of the default queue group + */ public static final String DEFAULT_QGROUP = "q"; private final String name; diff --git a/src/main/java/io/nats/service/InfoResponse.java b/src/main/java/io/nats/service/InfoResponse.java index 3c9228d5c..8d4f1e08d 100644 --- a/src/main/java/io/nats/service/InfoResponse.java +++ b/src/main/java/io/nats/service/InfoResponse.java @@ -32,6 +32,9 @@ * {"id":"JlkwZvmHAXCQGwwxiPwaBJ","name":"MyService","version":"0.0.1","endpoints":[{"name":"MyEndpoint","subject":"myend"}],"type":"io.nats.micro.v1.info_response"} */ public class InfoResponse extends ServiceResponse { + /** + * The API response type for InfoResponse + */ public static final String TYPE = "io.nats.micro.v1.info_response"; private final String description; diff --git a/src/main/java/io/nats/service/PingResponse.java b/src/main/java/io/nats/service/PingResponse.java index 70ce802b1..40c1cedab 100644 --- a/src/main/java/io/nats/service/PingResponse.java +++ b/src/main/java/io/nats/service/PingResponse.java @@ -20,6 +20,9 @@ * {"id":"JlkwZvmHAXCQGwwxiPwaBJ","name":"MyService","version":"0.0.1","type":"io.nats.micro.v1.ping_response"} */ public class PingResponse extends ServiceResponse { + /** + * The API response type for PingResponse + */ public static final String TYPE = "io.nats.micro.v1.ping_response"; PingResponse(String id, String name, String version, Map metadata) { diff --git a/src/main/java/io/nats/service/Service.java b/src/main/java/io/nats/service/Service.java index ddf4c3fc2..eceb834a3 100644 --- a/src/main/java/io/nats/service/Service.java +++ b/src/main/java/io/nats/service/Service.java @@ -39,9 +39,21 @@ * When multiple instances of a service endpoints are active they work in a queue, meaning only one listener responds to any given request. */ public class Service { + /** + * Constant for the PING service + */ public static final String SRV_PING = "PING"; + /** + * Constant for the INFO service + */ public static final String SRV_INFO = "INFO"; + /** + * Constant for the STATS service + */ public static final String SRV_STATS = "STATS"; + /** + * Constant of the service prefix + */ public static final String DEFAULT_SERVICE_PREFIX = "$SRV."; private final Connection conn; diff --git a/src/main/java/io/nats/service/ServiceBuilder.java b/src/main/java/io/nats/service/ServiceBuilder.java index 05336b3ac..c45d0295c 100644 --- a/src/main/java/io/nats/service/ServiceBuilder.java +++ b/src/main/java/io/nats/service/ServiceBuilder.java @@ -14,7 +14,14 @@ * Use the Service static method builder() or new ServiceBuilder() to get an instance. */ public class ServiceBuilder { + /** + * Constant for the default drain timeout in millis + */ public static final long DEFAULT_DRAIN_TIMEOUT_MILLIS = 5000; + + /** + * Constant for the default drain timeout as duration + */ public static final Duration DEFAULT_DRAIN_TIMEOUT = Duration.ofMillis(DEFAULT_DRAIN_TIMEOUT_MILLIS); Connection conn; @@ -28,6 +35,11 @@ public class ServiceBuilder { Dispatcher infoDispatcher; Dispatcher statsDispatcher; + /** + * Construct an instance of the builder + */ + public ServiceBuilder() {} + /** * The connection the service runs on * @param conn connection diff --git a/src/main/java/io/nats/service/ServiceEndpoint.java b/src/main/java/io/nats/service/ServiceEndpoint.java index 3f316943b..f32347b5e 100644 --- a/src/main/java/io/nats/service/ServiceEndpoint.java +++ b/src/main/java/io/nats/service/ServiceEndpoint.java @@ -136,6 +136,11 @@ public static class Builder { private Supplier statsDataSupplier; private Endpoint.Builder endpointBuilder = Endpoint.builder(); + /** + * Construct an instance of the builder + */ + public Builder() {} + /** * Set the {@link Group} for this ServiceEndpoint * @param group the group diff --git a/src/main/java/io/nats/service/ServiceMessage.java b/src/main/java/io/nats/service/ServiceMessage.java index 3e8588927..871460e6c 100644 --- a/src/main/java/io/nats/service/ServiceMessage.java +++ b/src/main/java/io/nats/service/ServiceMessage.java @@ -115,6 +115,7 @@ public void respondStandardError(Connection conn, String errorText, int errorCod } /** + * the subject that this message was sent to * @return the subject that this message was sent to */ public String getSubject() { @@ -122,6 +123,7 @@ public String getSubject() { } /** + * the subject the application is expected to send a reply message on * @return the subject the application is expected to send a reply message on */ public String getReplyTo() { @@ -129,6 +131,7 @@ public String getReplyTo() { } /** + * true if there are headers * @return true if there are headers */ public boolean hasHeaders() { @@ -136,6 +139,7 @@ public boolean hasHeaders() { } /** + * the headers object for the message * @return the headers object for the message */ public Headers getHeaders() { @@ -143,6 +147,7 @@ public Headers getHeaders() { } /** + * the data from the message * @return the data from the message */ public byte[] getData() { diff --git a/src/main/java/io/nats/service/StatsResponse.java b/src/main/java/io/nats/service/StatsResponse.java index ef52a21a7..0b411cb50 100644 --- a/src/main/java/io/nats/service/StatsResponse.java +++ b/src/main/java/io/nats/service/StatsResponse.java @@ -64,6 +64,9 @@ * */ public class StatsResponse extends ServiceResponse { + /** + * The API response type for StatsResponse + */ public static final String TYPE = "io.nats.micro.v1.stats_response"; private final ZonedDateTime started; diff --git a/src/test/java/io/nats/client/impl/ErrorListenerTests.java b/src/test/java/io/nats/client/impl/ErrorListenerTests.java index 725019d56..6bd7351a4 100644 --- a/src/test/java/io/nats/client/impl/ErrorListenerTests.java +++ b/src/test/java/io/nats/client/impl/ErrorListenerTests.java @@ -417,7 +417,7 @@ public void flowControlProcessed(Connection conn, JetStreamSubscription sub, Str _cover(new ReaderListenerConsoleImpl()); _cover(new ReadListener() { @Override - public void protocol(String op, String string) { + public void protocol(String op, String text) { } @Override