use of com.couchbase.client.core.env.CoreEnvironment in project couchbase-jvm-clients by couchbase.
the class BaseEndpoint method reconnect.
/**
* This method performs the actual connecting logic.
*
* <p>It is called reconnect since it works both in the case where an initial attempt is made
* but also when the underlying channel is closed or the previous connect attempt was
* unsuccessful.</p>
*/
private void reconnect() {
if (disconnect.get()) {
return;
}
state.transition(EndpointState.CONNECTING);
final EndpointContext endpointContext = this.endpointContext.get();
final AtomicLong attemptStart = new AtomicLong();
Mono.defer((Supplier<Mono<Channel>>) () -> {
CoreEnvironment env = endpointContext.environment();
long connectTimeoutMs = env.timeoutConfig().connectTimeout().toMillis();
if (eventLoopGroup.isShutdown()) {
throw new IllegalStateException("Event Loop is already shut down, not pursuing connect attempt!");
}
final Bootstrap channelBootstrap = new Bootstrap().remoteAddress(remoteAddress()).group(eventLoopGroup).channel(channelFrom(eventLoopGroup)).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, (int) connectTimeoutMs).handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(final Channel ch) {
ChannelPipeline pipeline = ch.pipeline();
SecurityConfig config = env.securityConfig();
if (config.tlsEnabled()) {
try {
pipeline.addFirst(SslHandlerFactory.get(ch.alloc(), config, endpointContext));
} catch (Exception e) {
throw new SecurityException("Could not instantiate SSL Handler", e);
}
}
if (env.ioConfig().servicesToCapture().contains(serviceType)) {
pipeline.addLast(new TrafficCaptureHandler(endpointContext));
}
pipelineInitializer().init(BaseEndpoint.this, pipeline);
pipeline.addLast(new PipelineErrorHandler(BaseEndpoint.this));
}
});
if (env.ioConfig().tcpKeepAlivesEnabled() && !(eventLoopGroup instanceof DefaultEventLoopGroup)) {
channelBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
if (eventLoopGroup instanceof EpollEventLoopGroup) {
channelBootstrap.option(EpollChannelOption.TCP_KEEPIDLE, (int) TimeUnit.MILLISECONDS.toSeconds(env.ioConfig().tcpKeepAliveTime().toMillis()));
}
}
state.transition(EndpointState.CONNECTING);
attemptStart.set(System.nanoTime());
return channelFutureIntoMono(channelBootstrap.connect());
}).timeout(endpointContext.environment().timeoutConfig().connectTimeout()).onErrorResume(throwable -> {
state.transition(EndpointState.DISCONNECTED);
if (disconnect.get()) {
endpointContext.environment().eventBus().publish(new EndpointConnectionAbortedEvent(Duration.ofNanos(System.nanoTime() - attemptStart.get()), endpointContext, ConnectTimings.toMap(channel)));
return Mono.empty();
} else {
return Mono.error(throwable);
}
}).retryWhen(Retry.any().exponentialBackoff(Duration.ofMillis(32), Duration.ofMillis(4096)).retryMax(Long.MAX_VALUE).doOnRetry(retryContext -> {
Throwable ex = retryContext.exception();
// We drop the severity for the BucketNotFoundException because it shows up when
// bootstrapping against MDS clusters and nodes with no kv service enabled on it
// that is bucket aware. If a bucket really does not exist we'll get an auth
// exception instead.
Event.Severity severity = ex instanceof BucketNotFoundException ? Event.Severity.DEBUG : Event.Severity.WARN;
Duration duration = ex instanceof TimeoutException ? endpointContext.environment().timeoutConfig().connectTimeout() : Duration.ofNanos(System.nanoTime() - attemptStart.get());
ex = annotateConnectException(ex);
endpointContext.environment().eventBus().publish(new EndpointConnectionFailedEvent(severity, duration, endpointContext, retryContext.iteration(), trimNettyFromStackTrace(ex)));
}).toReactorRetry()).subscribe(channel -> {
long now = System.nanoTime();
if (disconnect.get()) {
this.channel = null;
endpointContext.environment().eventBus().publish(new EndpointConnectionIgnoredEvent(Duration.ofNanos(now - attemptStart.get()), endpointContext, ConnectTimings.toMap(channel)));
closeChannel(channel);
} else {
this.channel = channel;
Optional<HostAndPort> localSocket = Optional.empty();
if (channel.localAddress() instanceof InetSocketAddress) {
// it will always be an inet socket address, but to safeguard for testing mocks...
InetSocketAddress so = (InetSocketAddress) channel.localAddress();
localSocket = Optional.of(new HostAndPort(so.getHostString(), so.getPort()));
}
EndpointContext newContext = new EndpointContext(endpointContext, endpointContext.remoteSocket(), endpointContext.circuitBreaker(), endpointContext.serviceType(), localSocket, endpointContext.bucket(), Optional.ofNullable(channel.attr(ChannelAttributes.CHANNEL_ID_KEY).get()));
this.endpointContext.get().environment().eventBus().publish(new EndpointConnectedEvent(Duration.ofNanos(now - attemptStart.get()), newContext, ConnectTimings.toMap(channel)));
this.endpointContext.set(newContext);
this.circuitBreaker.reset();
lastConnectedAt = now;
state.transition(EndpointState.CONNECTED);
}
}, error -> endpointContext.environment().eventBus().publish(new UnexpectedEndpointConnectionFailedEvent(Duration.ofNanos(System.nanoTime() - attemptStart.get()), endpointContext, error)));
}
use of com.couchbase.client.core.env.CoreEnvironment in project couchbase-jvm-clients by couchbase.
the class Node method createService.
/**
* Helper method to create the {@link Service} based on the service type provided.
*
* @param serviceType the type of service to create.
* @param port the port for that service.
* @param bucket optionally the bucket name.
* @return a created service, but not yet connected or anything.
*/
protected Service createService(final ServiceType serviceType, final int port, final Optional<String> bucket) {
CoreEnvironment env = ctx.environment();
String address = alternateAddress.orElseGet(identifier::address);
switch(serviceType) {
case KV:
return new KeyValueService(KeyValueServiceConfig.endpoints(env.ioConfig().numKvConnections()).build(), ctx, address, port, bucket, authenticator);
case MANAGER:
return new ManagerService(ctx, address, port);
case QUERY:
return new QueryService(QueryServiceConfig.maxEndpoints(env.ioConfig().maxHttpConnections()).idleTime(env.ioConfig().idleHttpConnectionTimeout()).build(), ctx, address, port);
case VIEWS:
return new ViewService(ViewServiceConfig.maxEndpoints(env.ioConfig().maxHttpConnections()).idleTime(env.ioConfig().idleHttpConnectionTimeout()).build(), ctx, address, port);
case SEARCH:
return new SearchService(SearchServiceConfig.maxEndpoints(env.ioConfig().maxHttpConnections()).idleTime(env.ioConfig().idleHttpConnectionTimeout()).build(), ctx, address, port);
case ANALYTICS:
return new AnalyticsService(AnalyticsServiceConfig.maxEndpoints(env.ioConfig().maxHttpConnections()).idleTime(env.ioConfig().idleHttpConnectionTimeout()).build(), ctx, address, port);
case EVENTING:
return new EventingService(ctx, address, port);
case BACKUP:
return new BackupService(ctx, address, port);
default:
throw InvalidArgumentException.fromMessage("Unsupported ServiceType: " + serviceType);
}
}
use of com.couchbase.client.core.env.CoreEnvironment in project couchbase-jvm-clients by couchbase.
the class TransportEncryptionIntegrationTest method performsKeyValueIgnoringServerCert.
@Test
void performsKeyValueIgnoringServerCert() throws Exception {
CoreEnvironment env = secureEnvironment(SecurityConfig.enableTls(true).trustManagerFactory(InsecureTrustManagerFactory.INSTANCE), null);
Core core = Core.create(env, authenticator(), secureSeeds());
core.openBucket(config().bucketname());
waitUntilCondition(() -> core.clusterConfig().hasClusterOrBucketConfig());
try {
runKeyValueOperation(core, env);
} finally {
core.shutdown().block();
env.shutdown();
}
}
use of com.couchbase.client.core.env.CoreEnvironment in project couchbase-jvm-clients by couchbase.
the class TransportEncryptionIntegrationTest method allowsToConfigureCustomCipher.
@Test
void allowsToConfigureCustomCipher() throws Exception {
if (!config().clusterCerts().isPresent()) {
fail("Cluster Certificate must be present for this test!");
}
CoreEnvironment env = secureEnvironment(SecurityConfig.enableTls(true).ciphers(Collections.singletonList("TLS_AES_256_GCM_SHA384")).trustCertificates(config().clusterCerts().get()), null);
Core core = Core.create(env, authenticator(), secureSeeds());
core.openBucket(config().bucketname());
waitUntilCondition(() -> core.clusterConfig().hasClusterOrBucketConfig());
try {
runKeyValueOperation(core, env);
} finally {
core.shutdown().block();
env.shutdown();
}
}
use of com.couchbase.client.core.env.CoreEnvironment in project couchbase-jvm-clients by couchbase.
the class TransportEncryptionIntegrationTest method loadsSecurityConfigFromTrustStore.
@Test
void loadsSecurityConfigFromTrustStore() throws Exception {
if (!config().clusterCerts().isPresent()) {
fail("Cluster Certificate must be present for this test!");
}
// Prepare a keystore and load it with the cert
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
trustStore.setCertificateEntry("server", config().clusterCerts().get().get(0));
CoreEnvironment env = secureEnvironment(SecurityConfig.enableTls(true).trustStore(trustStore), null);
Core core = Core.create(env, authenticator(), secureSeeds());
core.openBucket(config().bucketname());
waitUntilCondition(() -> core.clusterConfig().hasClusterOrBucketConfig());
try {
runKeyValueOperation(core, env);
} finally {
core.shutdown().block();
env.shutdown();
}
}
Aggregations