All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nats.client.Nats Maven / Gradle / Ivy

There is a newer version: 2.20.5
Show newest version
// 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.impl.NatsImpl;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

/**
 * The Nats class is the entry point into the NATS client for Java. This class
 * is used to create a connection to the NATS server. Connecting is a
 * synchronous process, with a new asynchronous version available for experimenting.
 * 
 * 

Simple connections can be created with a URL, while more control is provided * when an {@link Options Options} object is used. There are a number of options that * effect every connection, as described in the {@link Options Options} documentation. * *

At its simplest, you can connect to a nats-server on the local host using the default port with: *

Connection nc = Nats.connect()
*

and start sending or receiving messages immediately after that. * *

While the simple case relies on a single URL, the options allows you to configure a list of servers * that is used at connect time and during reconnect scenarios. * *

NATS supports TLS connections. This library relies on the standard SSLContext class to configure * SSL certificates and trust managers, as a result there are two steps to setting up a TLS connection, * configuring the SSL context and telling the library which one to use. Several options are provided * for each. To tell the library to connect with TLS: * *

    *
  • Pass a tls:// URL to the connect method, or as part of the options. The library will use the * default SSLContext for both the client certificates and trust managers. *
  • Call the {@link Options.Builder#secure() secure} method on the options builder, again the default * SSL Context is used. *
  • Call {@link Options.Builder#sslContext(javax.net.ssl.SSLContext) sslContext} when building your options. * Your context will be used. *
  • Pass an opentls:// url to the connect method, or in the options. The library will create a special * SSLContext that has no client certificates and trusts any server. This is less secure, but useful for * testing and behind a firewall. *
  • Call the {@link Options.Builder#opentls() opentls} method on the builder when creating your options, again * the all trusting, non-verifiable client is created. *
* *

To set up the default context for tls:// or {@link Options.Builder#secure() secure} you can: *

    *
  • Configure the default using System properties, i.e. javax.net.ssl.keyStore. *
  • Set the context manually with the SSLContext setDefault method. *
* *

If the server is configured to verify clients, the opentls mode will not work, and the other modes require a client certificate * to work. * *

Authentication, if configured on the server, is managed via the Options as well. However, the url passed to {@link #connect(String) connect()} * can provide a user/password pair or a token using the forms: {@code nats://user:password@server:port} and {@code nats://token@server:port}. * *

Regardless of the method used a {@link Connection Connection} object is created, and provides the methods for * sending, receiving and dispatching messages. */ public abstract class Nats { /** * Current version of the library */ public static final String CLIENT_VERSION; /** * Current language of the library - {@value} */ public static final String CLIENT_LANGUAGE = "java"; static { String cv; try { cv = Nats.class.getPackage().getImplementationVersion(); } catch (Exception ignore) { cv = null; } if (cv == null) { try { List lines = Files.readAllLines(new File("build.gradle").toPath()); for (String l : lines) { if (l.startsWith("def jarVersion")) { int at = l.indexOf('"'); int lat = l.lastIndexOf('"'); cv = l.substring(at + 1, lat) + ".dev"; break; } } } catch (Exception ignore) {} } CLIENT_VERSION = cv == null ? "development" : cv; } /** * Connect to the default URL, {@link Options#DEFAULT_URL Options.DEFAULT_URL}, with all the * default options. * *

This is a synchronous call, and the connection should be ready for use on return * there are network timing issues that could result in a successful connect call but * the connection is invalid soon after return, where soon is in the network/thread world. * *

If the connection fails, an IOException is thrown * *

See {@link Nats#connect(Options) connect(Options)} for more information on exceptions. * * @return the connection * @throws IOException if a networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connect() throws IOException, InterruptedException { Options options = new Options.Builder().server(Options.DEFAULT_URL).build(); return createConnection(options, false); } /** * Connect to the default URL, {@link Options#DEFAULT_URL Options.DEFAULT_URL}, with all the * default options, allowing re-connect attempts if the initial connection fails * @return the connection * @throws IOException if an unrecoverable networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connectReconnectOnConnect() throws IOException, InterruptedException { Options options = new Options.Builder().server(Options.DEFAULT_URL).build(); return createConnection(options, true); } /** * Connect to specific url, with all the default options. * The Java client generally expects URLs of the form {@code nats://hostname:port} * *

but also allows urls with a user password {@code nats://user:pass@hostname:port}.

* *

or token in them {@code nats://token@hostname:port}.

* *

Moreover, you can initiate a TLS connection, by using the `tls` * schema, which will use the default SSLContext, or fail if one is not set. For * testing and development, the `opentls` schema is support when the server is * in non-verify mode. In this case, the client will accept any server * certificate and will not provide one of its own.

* *

This is a synchronous call, and the connection should be ready for use on return * there are network timing issues that could result in a successful connect call but * the connection is invalid soon after return, where soon is in the network/thread world.

* *

If the connection fails, an IOException is thrown

* *

See {@link Nats#connect(Options) connect(Options)} for more information on exceptions.

* * @param url comma separated list of the URLs of the server, i.e. nats://localhost:4222,nats://localhost:4223 * @throws IOException if a networking issue occurs * @throws InterruptedException if the current thread is interrupted * @return the connection */ public static Connection connect(String url) throws IOException, InterruptedException { Options options = new Options.Builder().server(url).build(); return createConnection(options, false); } /** * Connect to specific url, with all the default options, * allowing re-connect attempts if the initial connection fails * @param url comma separated list of the URLs of the server, i.e. nats://localhost:4222,nats://localhost:4223 * @return the connection * @throws IOException if an unrecoverable networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connectReconnectOnConnect(String url) throws IOException, InterruptedException { Options options = new Options.Builder().server(url).build(); return createConnection(options, true); } /** * Connect to the specified URL with the specified auth handler. * *

This is a synchronous call, and the connection should be ready for use on return * there are network timing issues that could result in a successful connect call but * the connection is invalid soon after return, where soon is in the network/thread world. * *

If the connection fails, an IOException is thrown * *

See {@link Nats#connect(Options) connect(Options)} for more information on exceptions. * * @param url comma separated list of the URLs of the server, i.e. nats://localhost:4222,nats://localhost:4223 * @param handler the authentication handler implementation * @return the connection * @throws IOException if a networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connect(String url, AuthHandler handler) throws IOException, InterruptedException { Options options = new Options.Builder().server(url).authHandler(handler).build(); return createConnection(options, false); } /** * Connect to the specified URL with the specified auth handler, * allowing re-connect attempts if the initial connection fails * @param url comma separated list of the URLs of the server, i.e. nats://localhost:4222,nats://localhost:4223 * @param handler the authentication handler implementation * @return the connection * @throws IOException if an unrecoverable networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connectReconnectOnConnect(String url, AuthHandler handler) throws IOException, InterruptedException { Options options = new Options.Builder().server(url).authHandler(handler).build(); return createConnection(options, true); } /** * Options can be used to set the server URL, or multiple URLS, callback * handlers for various errors, and connection events. * *

This is a synchronous call, and the connection should be ready for use on return * there are network timing issues that could result in a successful connect call but * the connection is invalid soon after return, where soon is in the network/thread world. * *

If the connection fails, an IOException is thrown * *

As of 2.6 the connect call with throw an io.nats.AuthenticationException if an authentication * error occurred during connect, and the connect failed. Because multiple servers are tried, this exception * may not indicate a problem on the "last server" tried, only that all the servers were tried and at least * one failed because of authentication. In situations with heterogeneous authentication for multiple servers * you may need to use an ErrorListener to determine which one had the problem. Authentication failures are not * immediate connect failures because of the server list, and the existing 2.x API contract. * *

As of 2.6.1 authentication errors play an even stronger role. If a server returns an authentication error * twice without a successful connection, the connection is closed. This will require a reconnect scenario, since * the initial connection only tries each server one time. However, if you have two servers S1 and S2, and S1 returns * and authentication error on connect, but S2 succeeds. Later, if S2 fails and S1 returns the same error the connection * will be closed. However, if S1 succeeds on reconnect the "last error" will be cleared so it would be allowed to fail * again in the future. * * @param options the options object to use to create the connection * @return the connection * @throws IOException if a networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connect(Options options) throws IOException, InterruptedException { return createConnection(options, false); } /** * Connect, allowing re-connect attempts if the initial connection fails * @param options the options object to use to create the connection * @return the connection * @throws IOException if an unrecoverable networking issue occurs * @throws InterruptedException if the current thread is interrupted */ public static Connection connectReconnectOnConnect(Options options) throws IOException, InterruptedException { return createConnection(options, true); } /** * Try to connect in another thread, a connection listener is required to get * the connection. * *

Normally connect will loop through the available servers one time. If * reconnectOnConnect is true, the connection attempt will repeat based on the * settings in options, including indefinitely. * *

If there is an exception before a connection is created, and the error * listener is set, it will be notified with a null connection. * * @param options the connection options * @param reconnectOnConnect if true, the connection will treat the initial * connection as any other and attempt reconnects on * failure * * @throws IllegalArgumentException if no connection listener is set in the options * @throws InterruptedException if the current thread is interrupted */ public static void connectAsynchronously(Options options, boolean reconnectOnConnect) throws InterruptedException { if (options.getConnectionListener() == null) { throw new IllegalArgumentException("Connection Listener required in connectAsynchronously"); } Thread t = new Thread(() -> { try { NatsImpl.createConnection(options, reconnectOnConnect); } catch (Exception ex) { options.getErrorListener().exceptionOccurred(null, ex); } }); t.setName("NATS - async connection"); t.start(); } /** * Create an auth handler from a creds file. The handler will read the file each time it needs to respond to a request * and clear the memory after. This has a small price, but will only be encountered during connect or reconnect. * The creds file has a JWT - generally commented with a separator - followed by an nkey - also with a separator. * * @param credsFile a file containing a user JWT and an nkey * @return an AuthHandler that will use the creds file to load/clear the nkey and jwt as needed */ public static AuthHandler credentials(String credsFile) { return NatsImpl.credentials(credsFile); } /** * Create an AuthHandler from a jwt file and an nkey file. The handler will read the files each time it needs to respond to a request * and clear the memory after. This has a small price, but will only be encountered during connect or reconnect. * *

The {@code jwtFile} parameter can be set to {@code null} for challenge only authentication. * * @param jwtFile a file containing a user JWT, may or may not contain separators * @param nkeyFile a file containing a user nkey that matches the JWT, may or may not contain separators * @return an AuthHandler that will use the creds file to load/clear the nkey and jwt as needed */ public static AuthHandler credentials(String jwtFile, String nkeyFile) { return NatsImpl.credentials(jwtFile, nkeyFile); } /** * Create an auth handler from the data found in a credsFile. This credentials object is static, and will not change * over the course of its lifetime. Create a custom AuthHandler or use the file-based handler for dynamic credentials. * * @param credsBytes the contents of a user JWT file (optional if nkey authentication is being used) * @return an AuthHandler that will return the JWT, public key or sign a nonce appropriately */ public static AuthHandler staticCredentials(byte[] credsBytes) { return NatsImpl.staticCredentials(credsBytes); } /** * Create an auth handler from an nkey and an option JWT. This credentials object is static, and will not change * over the course of its lifetime. Create a custom AuthHandler or use the file-based handler for dynamic credentials. * * @param jwt the contents of a user JWT file (optional if nkey authentication is being used) * @param nkey an nkey seed * @return an AuthHandler that will return the JWT, public key or sign a nonce appropriately */ public static AuthHandler staticCredentials(char[] jwt, char[] nkey) { return NatsImpl.staticCredentials(jwt, nkey); } private static Connection createConnection(Options options, boolean reconnectOnConnect) throws IOException, InterruptedException { return NatsImpl.createConnection(options, reconnectOnConnect); } private Nats() {} /* ensures cannot be constructed */ }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy