void processSlowConsumer(Consumer consumer) { ErrorListener handler = this.options.getErrorListener(); if (handler != null && !this.callbackRunner.isShutdown()) { try { this.callbackRunner.execute(() -> { try { handler.slowConsumerDetected(this, consumer); } catch (Exception ex) { this.statistics.incrementExceptionCount(); } }); } catch (RejectedExecutionException re) { // Timing with shutdown, let it go } } }
void start(Future<DataPort> dataPortFuture) { this.dataPortFuture = dataPortFuture; this.running.set(true); this.stopped = new CompletableFuture<>(); // New future String name = (this.connection.getOptions().getConnectionName() != null) ? this.connection.getOptions().getConnectionName() : "Nats Connection"; this.thread = new Thread(this, name + " Writer"); this.thread.start(); }
void sendConnect(String serverURI) throws IOException { try { NatsServerInfo info = this.serverInfo.get(); StringBuilder connectString = new StringBuilder(); connectString.append(NatsConnection.OP_CONNECT); connectString.append(" "); String connectOptions = this.options.buildProtocolConnectOptionsString(serverURI, info.isAuthRequired(), info.getNonce()); connectString.append(connectOptions); NatsMessage msg = new NatsMessage(connectString.toString()); queueInternalOutgoing(msg); } catch (Exception exp) { exp.printStackTrace(); throw new IOException("Error sending connect string", exp); } }
NatsConnectionReader(NatsConnection connection) { this.connection = connection; this.running = new AtomicBoolean(false); this.stopped = new CompletableFuture<>(); this.stopped.complete(Boolean.TRUE); // we are stopped on creation this.protocolBuffer = ByteBuffer.allocate(this.connection.getOptions().getMaxControlLine()); this.msgLineChars = new char[this.connection.getOptions().getMaxControlLine()]; this.opArray = new char[MAX_PROTOCOL_OP_LENGTH]; this.buffer = new byte[connection.getOptions().getBufferSize()]; this.bufferPosition = 0; this.utf8Mode = connection.getOptions().supportUTF8Subjects(); }
public void connect(String serverURI, NatsConnection conn) throws IOException { try { this.connection = conn; Options options = this.connection.getOptions(); long timeout = options.getConnectionTimeout().toMillis(); URI uri = options.createURIForServer(serverURI); this.host = uri.getHost(); this.port = uri.getPort(); this.socket = new Socket(); socket.connect(new InetSocketAddress(host, port), (int) timeout); in = socket.getInputStream(); out = socket.getOutputStream(); } catch (Exception ex) { throw new IOException(ex); } }
appendOption(connectString, Options.OPTION_LANG, Nats.CLIENT_LANGUAGE, true, false); appendOption(connectString, Options.OPTION_VERSION, Nats.CLIENT_VERSION, true, true); appendOption(connectString, Options.OPTION_NAME, this.connectionName, true, true); appendOption(connectString, Options.OPTION_PROTOCOL, "1", false, true); appendOption(connectString, Options.OPTION_VERBOSE, String.valueOf(this.isVerbose()), false, true); appendOption(connectString, Options.OPTION_PEDANTIC, String.valueOf(this.isPedantic()), false, true); appendOption(connectString, Options.OPTION_TLS_REQUIRED, String.valueOf(this.isTLSRequired()), false, true); appendOption(connectString, Options.OPTION_ECHO, String.valueOf(!this.isNoEcho()), false, true); if (includeAuth && nonce != null && this.getAuthHandler() != null) { char[] nkey = this.getAuthHandler().getID(); byte[] sig = this.getAuthHandler().sign(nonce); char[] jwt = this.getAuthHandler().getJWT(); appendOption(connectString, Options.OPTION_NKEY, new String(nkey), true, true); // public key to string is ok appendOption(connectString, Options.OPTION_SIG, encodedSig, true, true); appendOption(connectString, Options.OPTION_JWT, new String(jwt), true, true); // public JWT to string is ok } else if (includeAuth) { String uriUser = null; URI uri = this.createURIForServer(serverURI); String userInfo = uri.getUserInfo(); appendOption(connectString, Options.OPTION_USER, uriUser, true, true); } else if (this.username != null) { appendOption(connectString, Options.OPTION_USER, this.username, true, true);
@Test public void testDefaultOptions() { Options o = new Options.Builder().build(); assertEquals("default one server", 1, o.getServers().size()); assertEquals("default url", Options.DEFAULT_URL, o.getServers().toArray()[0].toString()); assertEquals("default data port type", Options.DEFAULT_DATA_PORT_TYPE, o.getDataPortType()); assertEquals("default verbose", false, o.isVerbose()); assertEquals("default pedantic", false, o.isPedantic()); assertEquals("default norandomize", false, o.isNoRandomize()); assertEquals("default oldstyle", false, o.isOldRequestStyle()); assertEquals("default noEcho", false, o.isNoEcho()); assertEquals("default UTF8 Support", false, o.supportUTF8Subjects()); assertNull("default username", o.getUsername()); assertNull("default password", o.getPassword()); assertNull("default token", o.getToken()); assertNull("default connection name", o.getConnectionName()); assertNull("default ssl context", o.getSslContext()); assertEquals("default max reconnect", Options.DEFAULT_MAX_RECONNECT, o.getMaxReconnect()); assertEquals("default ping max", Options.DEFAULT_MAX_PINGS_OUT, o.getMaxPingsOut()); assertEquals("default reconnect buffer size", Options.DEFAULT_RECONNECT_BUF_SIZE, o.getReconnectBufferSize()); assertEquals("default reconnect wait", Options.DEFAULT_RECONNECT_WAIT, o.getReconnectWait()); assertEquals("default connection timeout", Options.DEFAULT_CONNECTION_TIMEOUT, o.getConnectionTimeout()); assertEquals("default ping interval", Options.DEFAULT_PING_INTERVAL, o.getPingInterval()); assertEquals("default cleanup interval", Options.DEFAULT_REQUEST_CLEANUP_INTERVAL, o.getRequestCleanupInterval()); assertNull("error handler", o.getErrorListener()); assertNull("disconnect handler", o.getConnectionListener()); }
@Test public void testPropertyIntOptions() { Properties props = new Properties(); props.setProperty(Options.PROP_MAX_RECONNECT, "100"); props.setProperty(Options.PROP_MAX_PINGS, "200"); props.setProperty(Options.PROP_RECONNECT_BUF_SIZE, "300"); props.setProperty(Options.PROP_MAX_CONTROL_LINE, "400"); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertEquals("property max reconnect", 100, o.getMaxReconnect()); assertEquals("property ping max", 200, o.getMaxPingsOut()); assertEquals("property reconnect buffer size", 300, o.getReconnectBufferSize()); assertEquals("property max control line", 400, o.getMaxControlLine()); }
@Test public void testPropertyDurationOptions() { Properties props = new Properties(); props.setProperty(Options.PROP_RECONNECT_WAIT, "101"); props.setProperty(Options.PROP_CONNECTION_TIMEOUT, "202"); props.setProperty(Options.PROP_PING_INTERVAL, "303"); props.setProperty(Options.PROP_CLEANUP_INTERVAL, "404"); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertEquals("property reconnect wait", Duration.ofMillis(101), o.getReconnectWait()); assertEquals("property connection timeout", Duration.ofMillis(202), o.getConnectionTimeout()); assertEquals("property ping interval", Duration.ofMillis(303), o.getPingInterval()); assertEquals("property cleanup interval", Duration.ofMillis(404), o.getRequestCleanupInterval()); }
@Test public void testDefaultPropertyIntOptions() { Properties props = new Properties(); props.setProperty(Options.PROP_RECONNECT_WAIT, "-1"); props.setProperty(Options.PROP_CONNECTION_TIMEOUT, "-1"); props.setProperty(Options.PROP_PING_INTERVAL, "-1"); props.setProperty(Options.PROP_CLEANUP_INTERVAL, "-1"); props.setProperty(Options.PROP_MAX_CONTROL_LINE, "-1"); Options o = new Options.Builder(props).build(); assertEquals("default max control line", Options.DEFAULT_MAX_CONTROL_LINE, o.getMaxControlLine()); assertEquals("default reconnect wait", Options.DEFAULT_RECONNECT_WAIT, o.getReconnectWait()); assertEquals("default connection timeout", Options.DEFAULT_CONNECTION_TIMEOUT, o.getConnectionTimeout()); assertEquals("default ping interval", Options.DEFAULT_PING_INTERVAL, o.getPingInterval()); assertEquals("default cleanup interval", Options.DEFAULT_REQUEST_CLEANUP_INTERVAL, o.getRequestCleanupInterval()); }
Duration connectTimeout = options.getConnectionTimeout(); DataPort newDataPort = this.options.buildDataPort(); newDataPort.connect(serverURI, this); this.timer = new Timer("Nats Connection Timer"); long pingMillis = this.options.getPingInterval().toMillis(); long cleanMillis = this.options.getRequestCleanupInterval().toMillis();
@Test public void testChainedConnectionListener() { ConnectionListener cHandler = (c, e) -> System.out.println("connection event" + e); Options o = new Options.Builder().connectionListener(cHandler).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertNull("error handler", o.getErrorListener()); assertTrue("chained connection handler", cHandler == o.getConnectionListener()); }
@Test public void testPropertiesStringOptions() throws NoSuchAlgorithmException { Properties props = new Properties(); props.setProperty(Options.PROP_USERNAME, "hello"); props.setProperty(Options.PROP_PASSWORD, "world"); props.setProperty(Options.PROP_CONNECTION_NAME, "name"); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertEquals("property username", "hello", o.getUsername()); assertEquals("property password", "world", o.getPassword()); assertEquals("property connection name", "name", o.getConnectionName()); }
@Test public void testPropertyErrorHandler() { Properties props = new Properties(); props.setProperty(Options.PROP_ERROR_LISTENER, TestHandler.class.getCanonicalName()); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertNotNull("property error handler", o.getErrorListener()); o.getErrorListener().errorOccurred(null, "bad subject"); assertEquals("property error handler class", ((TestHandler) o.getErrorListener()).getCount(), 1); }
throws InterruptedException { if (options.getConnectionListener() == null) { throw new IllegalArgumentException("Connection Listener required in connectAsynchronously"); NatsImpl.createConnection(options, reconnectOnConnect); } catch (Exception ex) { if (options.getErrorListener() != null) { options.getErrorListener().exceptionOccurred(null, ex);
@Test public void testChainOverridesProperties() throws NoSuchAlgorithmException { Properties props = new Properties(); props.setProperty(Options.PROP_TOKEN, "token"); props.setProperty(Options.PROP_CONNECTION_NAME, "name"); Options o = new Options.Builder(props).connectionName("newname").build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertEquals("property token", "token", o.getToken()); assertEquals("property connection name", "newname", o.getConnectionName()); }
/** * Upgrade the port to SSL. If it is already secured, this is a no-op. * If the data port type doesn't support SSL it should throw an exception. */ public void upgradeToSecure() throws IOException { Options options = this.connection.getOptions(); SSLContext context = options.getSslContext(); SSLSocketFactory factory = context.getSocketFactory(); Duration timeout = options.getConnectionTimeout(); this.sslSocket = (SSLSocket) factory.createSocket(socket, null, true); this.sslSocket.setUseClientMode(true); final CompletableFuture<Void> waitForHandshake = new CompletableFuture<>(); this.sslSocket.addHandshakeCompletedListener((evt) -> { waitForHandshake.complete(null); }); this.sslSocket.startHandshake(); try { waitForHandshake.get(timeout.toNanos(), TimeUnit.NANOSECONDS); } catch (Exception ex) { this.connection.handleCommunicationIssue(ex); } in = sslSocket.getInputStream(); out = sslSocket.getOutputStream(); }
void reconnect() throws InterruptedException { long maxTries = options.getMaxReconnect(); long tries = 0; String lastServer = null; this.flush(this.options.getConnectionTimeout()); } catch (Exception exp) { this.processException(exp);
@Test public void testPropertyConnectionListeners() { Properties props = new Properties(); props.setProperty(Options.PROP_CONNECTION_CB, TestHandler.class.getCanonicalName()); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertNotNull("property connection handler", o.getConnectionListener()); o.getConnectionListener().connectionEvent(null, Events.DISCONNECTED); o.getConnectionListener().connectionEvent(null, Events.RECONNECTED); o.getConnectionListener().connectionEvent(null, Events.CLOSED); assertEquals("property connect handler class", ((TestHandler) o.getConnectionListener()).getCount(), 3); }
@Test public void testPropertyDataPortType() { Properties props = new Properties(); props.setProperty(Options.PROP_DATA_PORT_TYPE, CloseOnUpgradeAttempt.class.getCanonicalName()); Options o = new Options.Builder(props).build(); assertEquals("default verbose", false, o.isVerbose()); // One from a different type assertEquals("property data port class", CloseOnUpgradeAttempt.class.getCanonicalName(), o.buildDataPort().getClass().getCanonicalName()); }