use of com.couchbase.client.core.service.Service in project couchbase-jvm-clients by couchbase.
the class NodeTest method degradedIfAtLeastOneConnected.
@Test
void degradedIfAtLeastOneConnected() {
Node node = new Node(CTX, mock(NodeIdentifier.class), NO_ALTERNATE) {
final AtomicInteger counter = new AtomicInteger();
@Override
protected Service createService(ServiceType serviceType, int port, Optional<String> bucket) {
Service s = mock(Service.class);
when(s.state()).thenReturn(counter.incrementAndGet() > 1 ? ServiceState.CONNECTED : ServiceState.DISCONNECTED);
when(s.states()).thenReturn(DirectProcessor.create());
return s;
}
};
assertEquals(NodeState.DISCONNECTED, node.state());
assertFalse(node.serviceEnabled(ServiceType.KV));
node.addService(ServiceType.KV, 11210, Optional.of("bucket")).block();
assertTrue(node.serviceEnabled(ServiceType.KV));
assertEquals(NodeState.DISCONNECTED, node.state());
assertFalse(node.serviceEnabled(ServiceType.QUERY));
node.addService(ServiceType.QUERY, 8093, Optional.empty()).block();
assertTrue(node.serviceEnabled(ServiceType.QUERY));
assertEquals(NodeState.DEGRADED, node.state());
assertFalse(node.serviceEnabled(ServiceType.VIEWS));
node.addService(ServiceType.VIEWS, 8092, Optional.empty()).block();
assertTrue(node.serviceEnabled(ServiceType.VIEWS));
assertEquals(NodeState.DEGRADED, node.state());
}
use of com.couchbase.client.core.service.Service in project couchbase-jvm-clients by couchbase.
the class Node method send.
/**
* Sends the request into this {@link Node}.
*
* <p>Note that there is no guarantee that the request will actually dispatched, based on the
* state this node is in.</p>
*
* @param request the request to send.
*/
public <R extends Request<? extends Response>> void send(final R request) {
String bucket;
if (request.serviceType().scope() == ServiceScope.BUCKET) {
bucket = request.bucket();
if (bucket == null) {
// no bucket name present so this is a kv request that is not attached
// to a specific bucket
bucket = BUCKET_GLOBAL_SCOPE;
}
} else {
bucket = GLOBAL_SCOPE;
}
Map<ServiceType, Service> scope = services.get(bucket);
if (scope == null) {
sendIntoRetry(request);
return;
}
Service service = scope.get(request.serviceType());
if (service == null) {
sendIntoRetry(request);
return;
}
request.context().lastDispatchedToNode(identifier);
service.send(request);
}
use of com.couchbase.client.core.service.Service in project couchbase-jvm-clients by couchbase.
the class Node method addService.
/**
* Adds a {@link Service} to this {@link Node}.
*
* @param type the type of the service.
* @param port the port of the service.
* @param bucket the bucket name (if present).
* @return a {@link Mono} that completes once the service is added.
*/
public synchronized Mono<Void> addService(final ServiceType type, final int port, final Optional<String> bucket) {
return Mono.defer(() -> {
if (disconnect.get()) {
ctx.environment().eventBus().publish(new ServiceAddIgnoredEvent(Event.Severity.DEBUG, ServiceAddIgnoredEvent.Reason.DISCONNECTED, ctx));
return Mono.empty();
}
String name = type.scope() == ServiceScope.CLUSTER ? GLOBAL_SCOPE : bucket.orElse(BUCKET_GLOBAL_SCOPE);
Map<ServiceType, Service> localMap = services.get(name);
if (localMap == null) {
localMap = new ConcurrentHashMap<>();
services.put(name, localMap);
}
if (!localMap.containsKey(type)) {
long start = System.nanoTime();
Service service = createService(type, port, bucket);
serviceStates.register(service, service);
localMap.put(type, service);
enabledServices.set(enabledServices.get() | 1 << type.ordinal());
// todo: only return once the service is connected?
service.connect();
long end = System.nanoTime();
ctx.environment().eventBus().publish(new ServiceAddedEvent(Duration.ofNanos(end - start), service.context()));
return Mono.empty();
} else {
ctx.environment().eventBus().publish(new ServiceAddIgnoredEvent(Event.Severity.VERBOSE, ServiceAddIgnoredEvent.Reason.ALREADY_ADDED, ctx));
return Mono.empty();
}
});
}
use of com.couchbase.client.core.service.Service in project couchbase-jvm-clients by couchbase.
the class NodeTest method retriesIfLocalServiceNotFound.
@Test
@SuppressWarnings({ "unchecked" })
void retriesIfLocalServiceNotFound() {
final Service s = mock(Service.class);
final AtomicReference<Request<?>> retried = new AtomicReference<>();
Node node = new Node(CTX, mock(NodeIdentifier.class), NO_ALTERNATE) {
@Override
protected Service createService(ServiceType serviceType, int port, Optional<String> bucket) {
when(s.state()).thenReturn(ServiceState.CONNECTED);
when(s.states()).thenReturn(DirectProcessor.create());
when(s.type()).thenReturn(serviceType);
return s;
}
@Override
protected <R extends Request<? extends Response>> void sendIntoRetry(R request) {
retried.set(request);
}
};
node.addService(ServiceType.KV, 11210, Optional.of("bucket")).block();
KeyValueRequest r = mock(KeyValueRequest.class);
when(r.serviceType()).thenReturn(ServiceType.KV);
when(r.bucket()).thenReturn("other_bucket");
node.send(r);
verify(s, never()).send(eq(r));
assertEquals(r, retried.get());
}
use of com.couchbase.client.core.service.Service in project couchbase-jvm-clients by couchbase.
the class NodeTest method canAddAndRemoveServices.
@Test
void canAddAndRemoveServices() {
Node node = new Node(CTX, mock(NodeIdentifier.class), NO_ALTERNATE) {
@Override
protected Service createService(ServiceType serviceType, int port, Optional<String> bucket) {
Service s = mock(Service.class);
when(s.state()).thenReturn(ServiceState.CONNECTED);
when(s.states()).thenReturn(DirectProcessor.create());
when(s.type()).thenReturn(serviceType);
return s;
}
};
assertEquals(NodeState.DISCONNECTED, node.state());
assertFalse(node.serviceEnabled(ServiceType.QUERY));
node.addService(ServiceType.QUERY, 8091, Optional.empty()).block();
assertTrue(node.serviceEnabled(ServiceType.QUERY));
assertEquals(NodeState.CONNECTED, node.state());
node.removeService(ServiceType.QUERY, Optional.empty()).block();
assertFalse(node.serviceEnabled(ServiceType.QUERY));
assertEquals(NodeState.DISCONNECTED, node.state());
}
Aggregations