Search in sources :

Example 1 with UpdateReaderGroupEvent

use of io.pravega.shared.controller.event.UpdateReaderGroupEvent in project pravega by pravega.

the class UpdateReaderGroupTask method execute.

@Override
public CompletableFuture<Void> execute(final UpdateReaderGroupEvent request) {
    String scope = request.getScope();
    String readerGroup = request.getRgName();
    long requestId = request.getRequestId();
    long generation = request.getGeneration();
    UUID readerGroupId = request.getReaderGroupId();
    boolean isTransition = request.isTransitionToFromSubscriber();
    ImmutableSet<String> streamsToBeUnsubscribed = request.getRemoveStreams();
    final OperationContext context = streamMetadataStore.createRGContext(scope, readerGroup, requestId);
    return RetryHelper.withRetriesAsync(() -> streamMetadataStore.getReaderGroupId(scope, readerGroup, context, executor).thenCompose(id -> {
        if (!id.equals(readerGroupId)) {
            log.warn(requestId, "Skipping processing of Reader Group update request {} as UUID did not match.", requestId);
            return CompletableFuture.completedFuture(null);
        }
        return streamMetadataStore.getReaderGroupConfigRecord(scope, readerGroup, context, executor).thenCompose(rgConfigRecord -> {
            if (rgConfigRecord.getObject().getGeneration() != generation) {
                log.warn(requestId, "Skipping processing of Reader Group update request as generation did not match.");
                return CompletableFuture.completedFuture(null);
            }
            if (rgConfigRecord.getObject().isUpdating()) {
                if (isTransition) {
                    // update Stream metadata tables, only if RG is a Subscriber
                    Iterator<String> streamIter = rgConfigRecord.getObject().getStartingStreamCuts().keySet().iterator();
                    String scopedRGName = NameUtils.getScopedReaderGroupName(scope, readerGroup);
                    Iterator<String> removeStreamsIter = streamsToBeUnsubscribed.stream().iterator();
                    return Futures.loop(removeStreamsIter::hasNext, () -> {
                        Stream stream = Stream.of(removeStreamsIter.next());
                        return streamMetadataStore.deleteSubscriber(stream.getScope(), stream.getStreamName(), scopedRGName, rgConfigRecord.getObject().getGeneration(), context, executor);
                    }, executor).thenCompose(v -> {
                        // updated config suggests this is a subscriber RG so addSubscriber
                        if (!ReaderGroupConfig.StreamDataRetention.NONE.equals(ReaderGroupConfig.StreamDataRetention.values()[rgConfigRecord.getObject().getRetentionTypeOrdinal()])) {
                            return Futures.loop(streamIter::hasNext, () -> {
                                Stream stream = Stream.of(streamIter.next());
                                return streamMetadataStore.addSubscriber(stream.getScope(), stream.getStreamName(), scopedRGName, rgConfigRecord.getObject().getGeneration(), context, executor);
                            }, executor);
                        }
                        return CompletableFuture.completedFuture(null);
                    }).thenCompose(v -> streamMetadataStore.completeRGConfigUpdate(scope, readerGroup, rgConfigRecord, context, executor));
                }
                // We get here for non-transition updates
                return streamMetadataStore.completeRGConfigUpdate(scope, readerGroup, rgConfigRecord, context, executor);
            }
            return CompletableFuture.completedFuture(null);
        });
    }), UPDATE_RETRY_PREDICATE, Integer.MAX_VALUE, executor);
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) OperationContext(io.pravega.controller.store.stream.OperationContext) NameUtils(io.pravega.shared.NameUtils) ImmutableSet(com.google.common.collect.ImmutableSet) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) ConnectionFailedException(io.pravega.shared.protocol.netty.ConnectionFailedException) Exceptions(io.pravega.common.Exceptions) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) UUID(java.util.UUID) TagLogger(io.pravega.common.tracing.TagLogger) Stream(io.pravega.client.stream.Stream) RetryableException(io.pravega.controller.retryable.RetryableException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamMetadataTasks(io.pravega.controller.task.Stream.StreamMetadataTasks) Preconditions(com.google.common.base.Preconditions) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) UpdateReaderGroupEvent(io.pravega.shared.controller.event.UpdateReaderGroupEvent) Futures(io.pravega.common.concurrent.Futures) ReaderGroupConfig(io.pravega.client.stream.ReaderGroupConfig) RetryHelper(io.pravega.controller.util.RetryHelper) Iterator(java.util.Iterator) Stream(io.pravega.client.stream.Stream) UUID(java.util.UUID)

Example 2 with UpdateReaderGroupEvent

use of io.pravega.shared.controller.event.UpdateReaderGroupEvent in project pravega by pravega.

the class StreamMetadataTasksTest method readerGroupFailureTests.

@Test(timeout = 30000)
public void readerGroupFailureTests() throws InterruptedException {
    WriterMock requestEventWriter = new WriterMock(streamMetadataTasks, executor);
    streamMetadataTasks.setRequestEventWriter(requestEventWriter);
    UpdateReaderGroupEvent badUpdateEvent = new UpdateReaderGroupEvent(SCOPE, "rg3", 2L, UUID.randomUUID(), 0L, false, ImmutableSet.of());
    requestEventWriter.writeEvent(badUpdateEvent);
    AssertExtensions.assertFutureThrows("DataNotFoundException", processFailingEvent(requestEventWriter), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException);
    String scopedStreamName = "scope/stream";
    ReaderGroupConfig rgConf = ReaderGroupConfig.builder().disableAutomaticCheckpoints().stream(scopedStreamName).retentionType(ReaderGroupConfig.StreamDataRetention.NONE).build();
    CreateReaderGroupEvent badCreateEvent = buildCreateRGEvent(SCOPE, "rg", rgConf, 1L, System.currentTimeMillis());
    requestEventWriter.writeEvent(badCreateEvent);
    AssertExtensions.assertFutureThrows("DataNotFoundException", processFailingEvent(requestEventWriter), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException);
    DeleteReaderGroupEvent badDeleteEvent = new DeleteReaderGroupEvent(SCOPE, "rg3", 1L, UUID.randomUUID());
    requestEventWriter.writeEvent(badDeleteEvent);
    AssertExtensions.assertFutureThrows("DataNotFoundException", processFailingEvent(requestEventWriter), e -> Exceptions.unwrap(e) instanceof StoreException.DataNotFoundException);
}
Also used : ReaderGroupConfig(io.pravega.client.stream.ReaderGroupConfig) CreateReaderGroupEvent(io.pravega.shared.controller.event.CreateReaderGroupEvent) DeleteReaderGroupEvent(io.pravega.shared.controller.event.DeleteReaderGroupEvent) UpdateReaderGroupEvent(io.pravega.shared.controller.event.UpdateReaderGroupEvent) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ControllerEventStreamWriterMock(io.pravega.controller.mocks.ControllerEventStreamWriterMock) EventStreamWriterMock(io.pravega.controller.mocks.EventStreamWriterMock) StoreException(io.pravega.controller.store.stream.StoreException) Test(org.junit.Test)

Example 3 with UpdateReaderGroupEvent

use of io.pravega.shared.controller.event.UpdateReaderGroupEvent in project pravega by pravega.

the class StreamMetadataTasks method updateReaderGroup.

/**
 * Update Reader Group Configuration.
 *
 * @param scope           Reader Group scope.
 * @param rgName          Reader Group name.
 * @param config          New Reader Group config.
 * @param requestId       request id.
 * @return updation status.
 */
public CompletableFuture<UpdateReaderGroupResponse> updateReaderGroup(final String scope, final String rgName, final ReaderGroupConfig config, long requestId) {
    final OperationContext context = streamMetadataStore.createRGContext(scope, rgName, requestId);
    return RetryHelper.withRetriesAsync(() -> {
        // 1. check if Reader Group exists...
        return streamMetadataStore.checkReaderGroupExists(scope, rgName, context, executor).thenCompose(exists -> {
            if (!exists) {
                UpdateReaderGroupResponse response = UpdateReaderGroupResponse.newBuilder().setStatus(UpdateReaderGroupResponse.Status.RG_NOT_FOUND).setGeneration(config.getGeneration()).build();
                return CompletableFuture.completedFuture(response);
            }
            // 2. check for generation && ID match with existing config
            return streamMetadataStore.getReaderGroupConfigRecord(scope, rgName, context, executor).thenCompose(rgConfigRecord -> {
                if (rgConfigRecord.getObject().getGeneration() != config.getGeneration()) {
                    UpdateReaderGroupResponse response = UpdateReaderGroupResponse.newBuilder().setStatus(UpdateReaderGroupResponse.Status.INVALID_CONFIG).setGeneration(config.getGeneration()).build();
                    return CompletableFuture.completedFuture(response);
                }
                if (!rgConfigRecord.getObject().isUpdating()) {
                    return streamMetadataStore.getReaderGroupId(scope, rgName, context, executor).thenCompose(rgId -> {
                        if (!config.getReaderGroupId().equals(rgId)) {
                            UpdateReaderGroupResponse response = UpdateReaderGroupResponse.newBuilder().setStatus(UpdateReaderGroupResponse.Status.INVALID_CONFIG).setGeneration(config.getGeneration()).build();
                            return CompletableFuture.completedFuture(response);
                        }
                        ImmutableSet<String> removeStreams = getStreamsToBeUnsubscribed(rgConfigRecord.getObject(), config);
                        boolean isTransition = isTransitionToOrFromSubscriber(rgConfigRecord.getObject(), config);
                        UpdateReaderGroupEvent event = new UpdateReaderGroupEvent(scope, rgName, requestId, rgId, rgConfigRecord.getObject().getGeneration() + 1, isTransition, removeStreams);
                        // 3. Create Reader Group Metadata and submit event
                        return eventHelperFuture.thenCompose(eventHelper -> eventHelper.addIndexAndSubmitTask(event, () -> streamMetadataStore.startRGConfigUpdate(scope, rgName, config, context, executor)).thenCompose(x -> eventHelper.checkDone(() -> isRGUpdated(scope, rgName, executor, context)).thenCompose(y -> streamMetadataStore.getReaderGroupConfigRecord(scope, rgName, context, executor).thenApply(configRecord -> {
                            UpdateReaderGroupResponse response = UpdateReaderGroupResponse.newBuilder().setStatus(UpdateReaderGroupResponse.Status.SUCCESS).setGeneration(configRecord.getObject().getGeneration()).build();
                            return response;
                        }))));
                    });
                } else {
                    log.error(requestId, "Reader group config update failed as another update was in progress.");
                    UpdateReaderGroupResponse response = UpdateReaderGroupResponse.newBuilder().setStatus(UpdateReaderGroupResponse.Status.FAILURE).setGeneration(config.getGeneration()).build();
                    return CompletableFuture.completedFuture(response);
                }
            });
        });
    }, e -> Exceptions.unwrap(e) instanceof RetryableException, READER_GROUP_OPERATION_MAX_RETRIES, executor);
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) UpdateStreamEvent(io.pravega.shared.controller.event.UpdateStreamEvent) StreamCut(io.pravega.controller.stream.api.grpc.v1.Controller.StreamCut) EventStreamWriter(io.pravega.client.stream.EventStreamWriter) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) AbstractStreamMetadataStore(io.pravega.controller.store.stream.AbstractStreamMetadataStore) StoreException(io.pravega.controller.store.stream.StoreException) TaskMetadataStore(io.pravega.controller.store.task.TaskMetadataStore) Duration(java.time.Duration) Map(java.util.Map) RGStreamCutRecord(io.pravega.shared.controller.event.RGStreamCutRecord) LockFailedException(io.pravega.controller.store.task.LockFailedException) ReaderGroupConfig(io.pravega.client.stream.ReaderGroupConfig) DeleteScopeStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteScopeStatus) StreamCutReferenceRecord(io.pravega.controller.store.stream.records.StreamCutReferenceRecord) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) DeleteStreamEvent(io.pravega.shared.controller.event.DeleteStreamEvent) Set(java.util.Set) GuardedBy(javax.annotation.concurrent.GuardedBy) ControllerEvent(io.pravega.shared.controller.event.ControllerEvent) Serializable(java.io.Serializable) ReaderGroupState(io.pravega.controller.store.stream.ReaderGroupState) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) Futures(io.pravega.common.concurrent.Futures) GrpcAuthHelper(io.pravega.controller.server.security.auth.GrpcAuthHelper) StreamMetrics(io.pravega.controller.metrics.StreamMetrics) CreateReaderGroupResponse(io.pravega.controller.stream.api.grpc.v1.Controller.CreateReaderGroupResponse) TransactionMetrics(io.pravega.controller.metrics.TransactionMetrics) RetentionPolicy(io.pravega.client.stream.RetentionPolicy) Exceptions(io.pravega.common.Exceptions) TruncateStreamEvent(io.pravega.shared.controller.event.TruncateStreamEvent) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet) Supplier(java.util.function.Supplier) UpdateSubscriberStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateSubscriberStatus) ArrayList(java.util.ArrayList) ReaderGroupConfigRecord(io.pravega.controller.store.stream.records.ReaderGroupConfigRecord) ReaderGroupConfiguration(io.pravega.controller.stream.api.grpc.v1.Controller.ReaderGroupConfiguration) StreamInfo(io.pravega.controller.stream.api.grpc.v1.Controller.StreamInfo) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) EventHelper(io.pravega.controller.task.EventHelper) CreateReaderGroupEvent(io.pravega.shared.controller.event.CreateReaderGroupEvent) RetryHelper(io.pravega.controller.util.RetryHelper) Task(io.pravega.controller.task.Task) Executor(java.util.concurrent.Executor) CreateStreamResponse(io.pravega.controller.store.stream.CreateStreamResponse) WireCommands(io.pravega.shared.protocol.netty.WireCommands) SegmentRange(io.pravega.controller.stream.api.grpc.v1.Controller.SegmentRange) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) TreeMap(java.util.TreeMap) WireCommandFailedException(io.pravega.controller.server.WireCommandFailedException) Preconditions(com.google.common.base.Preconditions) DeleteReaderGroupStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteReaderGroupStatus) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) ControllerEventProcessors(io.pravega.controller.server.eventProcessor.ControllerEventProcessors) StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) DeleteReaderGroupEvent(io.pravega.shared.controller.event.DeleteReaderGroupEvent) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) SealStreamEvent(io.pravega.shared.controller.event.SealStreamEvent) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) TaskStepsRetryHelper.withRetries(io.pravega.controller.task.Stream.TaskStepsRetryHelper.withRetries) Stream(io.pravega.client.stream.Stream) SubscribersResponse(io.pravega.controller.stream.api.grpc.v1.Controller.SubscribersResponse) Controller(io.pravega.controller.stream.api.grpc.v1.Controller) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) CreateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.CreateStreamStatus) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) EpochTransitionOperationExceptions(io.pravega.controller.store.stream.EpochTransitionOperationExceptions) DeleteScopeEvent(io.pravega.shared.controller.event.DeleteScopeEvent) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) RetriesExhaustedException(io.pravega.common.util.RetriesExhaustedException) List(java.util.List) Config(io.pravega.controller.util.Config) RetryableException(io.pravega.controller.retryable.RetryableException) Optional(java.util.Optional) Resource(io.pravega.controller.store.task.Resource) IntStream(java.util.stream.IntStream) OperationContext(io.pravega.controller.store.stream.OperationContext) SegmentHelper(io.pravega.controller.server.SegmentHelper) ModelHelper(io.pravega.client.control.impl.ModelHelper) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ScaleStatusResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleStatusResponse) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) BucketStore(io.pravega.controller.store.stream.BucketStore) DeleteStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteStreamStatus) EventStreamClientFactory(io.pravega.client.EventStreamClientFactory) NameUtils.getQualifiedStreamSegmentName(io.pravega.shared.NameUtils.getQualifiedStreamSegmentName) ScaleResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse) EventWriterConfig(io.pravega.client.stream.EventWriterConfig) ControllerService(io.pravega.controller.server.ControllerService) UpdateReaderGroupResponse(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateReaderGroupResponse) NameUtils(io.pravega.shared.NameUtils) Iterator(java.util.Iterator) TaskBase(io.pravega.controller.task.TaskBase) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) Timer(io.pravega.common.Timer) AbstractMap(java.util.AbstractMap) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) UpdateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateStreamStatus) State(io.pravega.controller.store.stream.State) VisibleForTesting(com.google.common.annotations.VisibleForTesting) UpdateReaderGroupEvent(io.pravega.shared.controller.event.UpdateReaderGroupEvent) Comparator(java.util.Comparator) ReaderGroupConfigResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ReaderGroupConfigResponse) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent) RetryableException(io.pravega.controller.retryable.RetryableException) UpdateReaderGroupEvent(io.pravega.shared.controller.event.UpdateReaderGroupEvent) UpdateReaderGroupResponse(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateReaderGroupResponse)

Aggregations

ReaderGroupConfig (io.pravega.client.stream.ReaderGroupConfig)3 UpdateReaderGroupEvent (io.pravega.shared.controller.event.UpdateReaderGroupEvent)3 Preconditions (com.google.common.base.Preconditions)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 Stream (io.pravega.client.stream.Stream)2 Exceptions (io.pravega.common.Exceptions)2 Futures (io.pravega.common.concurrent.Futures)2 TagLogger (io.pravega.common.tracing.TagLogger)2 RetryableException (io.pravega.controller.retryable.RetryableException)2 OperationContext (io.pravega.controller.store.stream.OperationContext)2 StoreException (io.pravega.controller.store.stream.StoreException)2 CreateReaderGroupEvent (io.pravega.shared.controller.event.CreateReaderGroupEvent)2 DeleteReaderGroupEvent (io.pravega.shared.controller.event.DeleteReaderGroupEvent)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 EventStreamClientFactory (io.pravega.client.EventStreamClientFactory)1 ModelHelper (io.pravega.client.control.impl.ModelHelper)1 EventStreamWriter (io.pravega.client.stream.EventStreamWriter)1 EventWriterConfig (io.pravega.client.stream.EventWriterConfig)1 RetentionPolicy (io.pravega.client.stream.RetentionPolicy)1