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

se.hiq.oss.spring.nats.connection.ConnectionFactoryBean Maven / Gradle / Ivy

There is a newer version: 0.15
Show newest version
package se.hiq.oss.spring.nats.connection;

import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.lang.Nullable;

import io.nats.client.Connection;
import io.nats.client.ConnectionListener;
import io.nats.client.ErrorListener;
import io.nats.client.Nats;
import io.nats.client.Options;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import se.hiq.oss.spring.nats.connection.tls.SslContextBuilder;
import se.hiq.oss.spring.nats.connection.tls.SslContextBuilderFactory;
import se.hiq.oss.spring.nats.jwt.JwtAuth;

public class ConnectionFactoryBean extends AbstractFactoryBean {
    private static final Logger LOG = LoggerFactory.getLogger(ConnectionFactoryBean.class);

    private List urls = List.of(Options.DEFAULT_URL);
    private int maxReconnects = Options.DEFAULT_MAX_RECONNECT;
    private Duration drainTimeout = Options.DEFAULT_CONNECTION_TIMEOUT;
    private String connectionName;
    private ErrorListener errorListener;
    private ConnectionListener connectionListener;
    private Duration connectionTimeout = Options.DEFAULT_CONNECTION_TIMEOUT;
    private String username;
    private String password;
    private TlsConfiguration tlsConfiguration = new TlsConfiguration();
    private SslContextBuilderFactory factory = new SslContextBuilderFactory();
    private String jwtToken;
    private String jwtNKey;



    private void configureCredentials(Options.Builder options) {
        if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            options.userInfo(username, password);
        } else if (!StringUtils.isEmpty(username) || !StringUtils.isEmpty(password)) {
            LOG.warn("Both username and password needs to be set, skipping since both is not set.");
        }

    }

    private void configureJwt(Options.Builder options) {
        if (!StringUtils.isEmpty(jwtToken) && !StringUtils.isEmpty(jwtNKey)) {
            options.authHandler(new JwtAuth(jwtToken, jwtNKey));
        } else if (!StringUtils.isEmpty(username) || !StringUtils.isEmpty(password)) {
            LOG.warn("Both token and n-key needs to be set, skipping since both is not set.");
        }

    }

    private void configureSSL(Options.Builder options) {

        try {
            if (tlsConfiguration.getTrustStore() == null) {
                options.opentls();
            } else {
                SslContextBuilder sslContextBuilder = factory.create(tlsConfiguration.getTrustStore(),
                        tlsConfiguration.getTrustStorePassword());
                if (tlsConfiguration.getIdentityStore() != null) {
                    sslContextBuilder.identityStore(tlsConfiguration.getIdentityStore(), tlsConfiguration.getIdentityStorePassword());
                }
                options.sslContext(sslContextBuilder.build());
            }
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("Could not enable tls", e);
        }

    }

    @Override
    public Class getObjectType() {
        return Connection.class;
    }

    @Override
    protected Connection createInstance() throws Exception {
        Options.Builder options = new Options.Builder()
                .servers(urls.stream().toArray(String[]::new))
                .connectionTimeout(connectionTimeout)
                .maxReconnects(maxReconnects);

        if (!StringUtils.isEmpty(connectionName)) {
            options.connectionName(connectionName);
        }
        if (errorListener != null) {
            options.errorListener(errorListener);
        }
        if (connectionListener != null) {
            options.connectionListener(connectionListener);
        }
        configureCredentials(options);
        if (tlsConfiguration != null && tlsConfiguration.isEnabled()) {
            configureSSL(options);
        }
        configureJwt(options);
        return Nats.connect(options.build());
    }

    @Override
    protected void destroyInstance(@Nullable Connection instance) throws Exception {
        if (instance != null) {
            CompletableFuture drainFuture = instance.drain(drainTimeout);
            drainFuture.join();
            instance.close();
        }
    }

    @Override
    public boolean isSingleton() {
        return true;
    }


    public void setUrls(List urls) {
        this.urls = urls;
    }

    public void setMaxReconnects(int maxReconnects) {
        this.maxReconnects = maxReconnects;
    }

    public void setConnectionName(String connectionName) {
        this.connectionName = connectionName;
    }

    public void setErrorListener(ErrorListener errorListener) {
        this.errorListener = errorListener;
    }

    public void setConnectionListener(ConnectionListener connectionListener) {
        this.connectionListener = connectionListener;
    }

    public void setConnectionTimeout(Duration connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setTlsConfiguration(TlsConfiguration tlsConfiguration) {
        this.tlsConfiguration = tlsConfiguration;
    }

    public void setJwtToken(String jwtToken) {
        this.jwtToken = jwtToken;
    }

    public void setJwtNKey(String jwtNKey) {
        this.jwtNKey = jwtNKey;
    }

    public void setDrainTimeout(Duration drainTimeout) {
        this.drainTimeout = drainTimeout;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy