use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.
the class HealthPinger method pingKv.
private static Mono<EndpointPingReport> pingKv(final Core core, final RequestTarget target, final CoreCommonOptions options) {
return Mono.defer(() -> {
Duration timeout = options.timeout().orElse(core.context().environment().timeoutConfig().kvTimeout());
CollectionIdentifier collectionIdentifier = CollectionIdentifier.fromDefault(target.bucketName());
KvPingRequest request = new KvPingRequest(timeout, core.context(), options.retryStrategy().orElse(null), collectionIdentifier, target.nodeIdentifier());
core.send(request);
return Reactor.wrap(request, request.response(), true).map(response -> {
request.context().logicallyComplete();
return assembleSuccessReport(request.context(), ((KvPingResponse) response).channelId(), Optional.ofNullable(target.bucketName()));
}).onErrorResume(throwable -> {
request.context().logicallyComplete();
return Mono.just(assembleFailureReport(throwable, request.context(), Optional.ofNullable(target.bucketName())));
});
});
}
use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.
the class TracingUtils method setCommonKVSpanAttributes.
/**
* Sets attributes that are usefully duplicated across multiple spans.
*/
public static void setCommonKVSpanAttributes(final RequestSpan span, final KeyValueRequest<Response> request) {
CollectionIdentifier collectionIdentifier = request.collectionIdentifier();
if (collectionIdentifier != null) {
span.attribute(TracingIdentifiers.ATTR_NAME, collectionIdentifier.bucket());
span.attribute(TracingIdentifiers.ATTR_SCOPE, collectionIdentifier.scope().orElse(CollectionIdentifier.DEFAULT_SCOPE));
span.attribute(TracingIdentifiers.ATTR_COLLECTION, collectionIdentifier.collection().orElse(CollectionIdentifier.DEFAULT_COLLECTION));
}
span.attribute(TracingIdentifiers.ATTR_DOCUMENT_ID, new String(request.key()));
if (request instanceof SyncDurabilityRequest) {
SyncDurabilityRequest syncDurabilityRequest = (SyncDurabilityRequest) request;
if (syncDurabilityRequest.durabilityLevel() != null) {
span.attribute(TracingIdentifiers.ATTR_DURABILITY, syncDurabilityRequest.durabilityLevel().map(Enum::name).orElse(DurabilityLevel.NONE.name()));
}
}
}
use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.
the class KeyValueBucketRefresher method fetchConfigPerNode.
/**
* Helper method to fetch a config per node provided.
*
* <p>Note that the bucket config request sent here has a fail fast strategy, so that if nodes are offline they
* do not circle the system forever (given they have a specific node target). Since the refresher polls every
* fixed interval anyways, fresh requests will flood the system eventually and there is no point in keeping
* the old ones around.</p>
*
* <p>Also, the timeout is set to the poll interval since it does not make sense to keep them around any
* longer.</p>
*
* @param name the bucket name.
* @param nodes the flux of nodes that can be used to fetch a config.
* @return returns configs for each node if found.
*/
private Flux<ProposedBucketConfigContext> fetchConfigPerNode(final String name, final Flux<NodeInfo> nodes) {
return nodes.flatMap(nodeInfo -> {
CoreContext ctx = core.context();
CarrierBucketConfigRequest request = new CarrierBucketConfigRequest(configRequestTimeout, ctx, new CollectionIdentifier(name, Optional.empty(), Optional.empty()), FailFastRetryStrategy.INSTANCE, nodeInfo.identifier());
core.send(request);
return Reactor.wrap(request, request.response(), true).filter(response -> {
if (!response.status().success()) {
eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.INDIVIDUAL_REQUEST_FAILED, Optional.of(response)));
}
return response.status().success();
}).map(response -> new ProposedBucketConfigContext(name, new String(response.content(), UTF_8), nodeInfo.hostname())).onErrorResume(t -> {
eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.INDIVIDUAL_REQUEST_FAILED, Optional.of(t)));
return Mono.empty();
});
});
}
use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.
the class AsyncCollection method lookupInRequest.
/**
* Helper method to create the underlying lookup subdoc request.
*
* @param id the outer document ID.
* @param specs the spec which specifies the type of lookups to perform.
* @param opts custom options to modify the lookup options.
* @return the subdoc lookup request.
*/
SubdocGetRequest lookupInRequest(final String id, final List<LookupInSpec> specs, final LookupInOptions.Built opts) {
notNullOrEmpty(id, "Id", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier));
notNullOrEmpty(specs, "LookupInSpecs", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier));
ArrayList<SubdocGetRequest.Command> commands = new ArrayList<>(specs.size());
for (int i = 0; i < specs.size(); i++) {
LookupInSpec spec = specs.get(i);
commands.add(spec.export(i));
}
// xattrs come first
commands.sort(Comparator.comparing(v -> !v.xattr()));
Duration timeout = opts.timeout().orElse(environment.timeoutConfig().kvTimeout());
RetryStrategy retryStrategy = opts.retryStrategy().orElse(environment.retryStrategy());
byte flags = 0;
if (opts.accessDeleted()) {
flags |= SubdocMutateRequest.SUBDOC_DOC_FLAG_ACCESS_DELETED;
}
RequestSpan span = environment.requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_LOOKUP_IN, opts.parentSpan().orElse(null));
SubdocGetRequest request = new SubdocGetRequest(timeout, coreContext, collectionIdentifier, retryStrategy, id, flags, commands, span);
request.context().clientContext(opts.clientContext());
return request;
}
use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.
the class ReactiveBatchHelper method existsBytes.
/**
* Performs the bulk logic of fetching a config and splitting up the observe requests.
*
* @param collection the collection on which the query should be performed.
* @param ids the list of ids which should be checked.
* @return a flux of all
*/
private static Flux<byte[]> existsBytes(final Collection collection, final java.util.Collection<String> ids) {
final Core core = collection.core();
final CoreEnvironment env = core.context().environment();
BucketConfig config = core.clusterConfig().bucketConfig(collection.bucketName());
if (core.configurationProvider().bucketConfigLoadInProgress() || config == null) {
// and then try again. In a steady state this should not happen.
return Mono.delay(Duration.ofMillis(100), env.scheduler()).flatMapMany(ign -> existsBytes(collection, ids));
}
long start = System.nanoTime();
if (!(config instanceof CouchbaseBucketConfig)) {
throw new IllegalStateException("Only couchbase (and ephemeral) buckets are supported at this point!");
}
Map<NodeIdentifier, Map<byte[], Short>> nodeEntries = new HashMap<>(config.nodes().size());
for (NodeInfo node : config.nodes()) {
nodeEntries.put(node.identifier(), new HashMap<>(ids.size() / config.nodes().size()));
}
CouchbaseBucketConfig cbc = (CouchbaseBucketConfig) config;
CollectionIdentifier ci = new CollectionIdentifier(collection.bucketName(), Optional.of(collection.scopeName()), Optional.of(collection.name()));
for (String id : ids) {
byte[] encodedId = id.getBytes(StandardCharsets.UTF_8);
int partitionId = KeyValueLocator.partitionForKey(encodedId, cbc.numberOfPartitions());
int nodeId = cbc.nodeIndexForActive(partitionId, false);
NodeInfo nodeInfo = cbc.nodeAtIndex(nodeId);
nodeEntries.get(nodeInfo.identifier()).put(encodedId, (short) partitionId);
}
List<Mono<MultiObserveViaCasResponse>> responses = new ArrayList<>(nodeEntries.size());
List<MultiObserveViaCasRequest> requests = new ArrayList<>(nodeEntries.size());
for (Map.Entry<NodeIdentifier, Map<byte[], Short>> node : nodeEntries.entrySet()) {
if (node.getValue().isEmpty()) {
// service enabled and 2) have keys that we need to fetch
continue;
}
MultiObserveViaCasRequest request = new MultiObserveViaCasRequest(env.timeoutConfig().kvTimeout(), core.context(), env.retryStrategy(), ci, node.getKey(), node.getValue(), PMGET_PREDICATE);
core.send(request);
requests.add(request);
responses.add(Reactor.wrap(request, request.response(), true));
}
return Flux.merge(responses).flatMap(response -> Flux.fromIterable(response.observed().keySet())).onErrorMap(throwable -> {
BatchErrorContext ctx = new BatchErrorContext(Collections.unmodifiableList(requests));
return new BatchHelperFailureException("Failed to perform BatchHelper bulk operation", throwable, ctx);
}).doOnComplete(() -> core.context().environment().eventBus().publish(new BatchHelperExistsCompletedEvent(Duration.ofNanos(System.nanoTime() - start), new BatchErrorContext(Collections.unmodifiableList(requests)))));
}
Aggregations