use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.
the class DeleteStreamTask method deleteAssociatedStreams.
private CompletableFuture<Void> deleteAssociatedStreams(String scope, String stream, long requestId) {
String markStream = NameUtils.getMarkStreamForStream(stream);
OperationContext context = streamMetadataStore.createStreamContext(scope, markStream, requestId);
return Futures.exceptionallyExpecting(notifyAndDelete(context, scope, markStream, requestId), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, null);
}
use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.
the class ScaleOperationTask method execute.
@Override
public CompletableFuture<Void> execute(final ScaleOpEvent request) {
CompletableFuture<Void> result = new CompletableFuture<>();
long requestId = request.getRequestId();
final OperationContext context = streamMetadataStore.createStreamContext(request.getScope(), request.getStream(), requestId);
log.info(requestId, "starting scale request for {}/{} segments {} to new ranges {}", request.getScope(), request.getStream(), request.getSegmentsToSeal(), request.getNewRanges());
runScale(request, request.isRunOnlyIfStarted(), context).whenCompleteAsync((res, e) -> {
if (e != null) {
Throwable cause = Exceptions.unwrap(e);
if (cause instanceof RetriesExhaustedException) {
cause = cause.getCause();
}
if (cause instanceof EpochTransitionOperationExceptions.PreConditionFailureException) {
log.info(requestId, "processing scale request for {}/{} segments {} failed {}", request.getScope(), request.getStream(), request.getSegmentsToSeal(), cause.getClass().getName());
result.complete(null);
} else {
log.warn(requestId, "processing scale request for {}/{} segments {} failed {}", request.getScope(), request.getStream(), request.getSegmentsToSeal(), cause);
result.completeExceptionally(cause);
}
} else {
log.info(requestId, "scale request for {}/{} segments {} to new ranges {} completed successfully.", request.getScope(), request.getStream(), request.getSegmentsToSeal(), request.getNewRanges());
result.complete(null);
}
}, executor);
return result;
}
use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.
the class PravegaTablesScope method readAll.
private CompletableFuture<Pair<List<String>, String>> readAll(int limit, String continuationToken, String tableName, OperationContext context) {
List<String> taken = new ArrayList<>();
AtomicReference<String> token = new AtomicReference<>(continuationToken);
AtomicBoolean canContinue = new AtomicBoolean(true);
return Futures.exceptionallyExpecting(storeHelper.getKeysPaginated(tableName, Unpooled.wrappedBuffer(Base64.getDecoder().decode(token.get())), limit, context.getRequestId()).thenApply(result -> {
if (result.getValue().isEmpty()) {
canContinue.set(false);
} else {
taken.addAll(result.getValue());
}
token.set(Base64.getEncoder().encodeToString(result.getKey().array()));
return new ImmutablePair<>(taken, token.get());
}), DATA_NOT_FOUND_PREDICATE, new ImmutablePair<>(Collections.emptyList(), token.get()));
}
use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.
the class TableMetadataTasks method createKeyValueTable.
/**
* Create a Key-Value Table.
*
* @param scope scope name.
* @param kvtName KVTable name.
* @param kvtConfig KVTable configuration.
* @param createTimestamp KVTable creation timestamp.
* @param requestId request id
* @return update status.
*/
public CompletableFuture<CreateKeyValueTableStatus.Status> createKeyValueTable(String scope, String kvtName, KeyValueTableConfiguration kvtConfig, final long createTimestamp, long requestId) {
OperationContext context = kvtMetadataStore.createContext(scope, kvtName, requestId);
return RetryHelper.withRetriesAsync(() -> {
// 1. check if scope with this name exists...
return kvtMetadataStore.checkScopeExists(scope, context, executor).thenCompose(exists -> {
if (!exists) {
return CompletableFuture.completedFuture(CreateKeyValueTableStatus.Status.SCOPE_NOT_FOUND);
}
return kvtMetadataStore.isScopeSealed(scope, context, executor).thenCompose(isScopeSealed -> {
if (isScopeSealed) {
return CompletableFuture.completedFuture(CreateKeyValueTableStatus.Status.SCOPE_NOT_FOUND);
}
// 2. check state of the KVTable, if found
return Futures.exceptionallyExpecting(kvtMetadataStore.getState(scope, kvtName, true, context, executor), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, KVTableState.UNKNOWN).thenCompose(state -> {
if (state.equals(KVTableState.UNKNOWN) || state.equals(KVTableState.CREATING)) {
// 3. get a new UUID for the KVTable we will be creating.
UUID id = kvtMetadataStore.newScope(scope).newId();
CreateTableEvent event = new CreateTableEvent(scope, kvtName, kvtConfig.getPartitionCount(), kvtConfig.getPrimaryKeyLength(), kvtConfig.getSecondaryKeyLength(), createTimestamp, requestId, id, kvtConfig.getRolloverSizeBytes());
// 4. Update ScopeTable with the entry for this KVT and Publish the event for creation
return eventHelper.addIndexAndSubmitTask(event, () -> kvtMetadataStore.createEntryForKVTable(scope, kvtName, id, context, executor)).thenCompose(x -> isCreateProcessed(scope, kvtName, kvtConfig, createTimestamp, executor, context));
}
log.info(requestId, "KeyValue table {}/{} already exists", scope, kvtName);
return isCreateProcessed(scope, kvtName, kvtConfig, createTimestamp, executor, context);
});
});
});
}, e -> Exceptions.unwrap(e) instanceof RetryableException, NUM_RETRIES, executor);
}
use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.
the class StreamMetadataTasks method deleteStream.
public CompletableFuture<DeleteStreamStatus.Status> deleteStream(final String scope, final String stream, final OperationContext context) {
Preconditions.checkNotNull(context, "Operation Context is null");
// We can delete streams only if they are sealed. However, for partially created streams, they could be in different
// stages of partial creation and we should be able to clean them up.
// Case 1: A partially created stream may just have some initial metadata created, in which case the Stream's state may not
// have been set up it may be present under the scope.
// In this case we can simply delete all metadata for the stream directly.
// Case 2: A partially created stream could be in state CREATING, in which case it would definitely have metadata created
// and possibly segments too. This requires same clean up as for a sealed stream - metadata + segments.
// So we will submit delete workflow.
long requestId = context.getRequestId();
return eventHelperFuture.thenCompose(eventHelper -> Futures.exceptionallyExpecting(streamMetadataStore.getState(scope, stream, false, context, executor), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException, State.UNKNOWN).thenCompose(state -> {
if (State.SEALED.equals(state) || State.CREATING.equals(state)) {
return streamMetadataStore.getCreationTime(scope, stream, context, executor).thenApply(time -> new DeleteStreamEvent(scope, stream, requestId, time)).thenCompose(eventHelper::writeEvent).thenApply(x -> true);
} else if (State.UNKNOWN.equals(state)) {
// so we can simply delete the stream metadata which deletes stream from scope as well.
return streamMetadataStore.deleteStream(scope, stream, context, executor).exceptionally(e -> {
throw new CompletionException(e);
}).thenApply(v -> true);
} else {
// we cannot delete the stream. Return false from here.
return CompletableFuture.completedFuture(false);
}
}).thenCompose(result -> {
if (result) {
return eventHelper.checkDone(() -> isDeleted(scope, stream, context)).thenApply(x -> DeleteStreamStatus.Status.SUCCESS);
} else {
return CompletableFuture.completedFuture(DeleteStreamStatus.Status.STREAM_NOT_SEALED);
}
})).exceptionally(ex -> {
return handleDeleteStreamError(ex, requestId, NameUtils.getScopedStreamName(scope, stream));
});
}
Aggregations