Search in sources :

Example 1 with ScaleOpEvent

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

the class StreamMetadataTasks method manualScale.

/**
 * Helper method to perform scale operation against an scale request.
 * This method posts a request in the request stream and then starts the scale operation while
 * tracking it's progress. Eventually, after scale completion, it sends a response to the caller.
 *
 * @param scope          scope.
 * @param stream         stream name.
 * @param segmentsToSeal segments to be sealed.
 * @param newRanges      key ranges for new segments.
 * @param scaleTimestamp scaling time stamp.
 * @param requestId      request id
 * @return returns the newly created segments.
 */
public CompletableFuture<ScaleResponse> manualScale(String scope, String stream, List<Long> segmentsToSeal, List<Map.Entry<Double, Double>> newRanges, long scaleTimestamp, long requestId) {
    final OperationContext context = streamMetadataStore.createStreamContext(scope, stream, requestId);
    ScaleOpEvent event = new ScaleOpEvent(scope, stream, segmentsToSeal, newRanges, true, scaleTimestamp, requestId);
    return eventHelperFuture.thenCompose(eventHelper -> eventHelper.addIndexAndSubmitTask(event, () -> streamMetadataStore.submitScale(scope, stream, segmentsToSeal, new ArrayList<>(newRanges), scaleTimestamp, null, context, executor)).handle((startScaleResponse, e) -> {
        ScaleResponse.Builder response = ScaleResponse.newBuilder();
        if (e != null) {
            Throwable cause = Exceptions.unwrap(e);
            if (cause instanceof EpochTransitionOperationExceptions.PreConditionFailureException) {
                response.setStatus(ScaleResponse.ScaleStreamStatus.PRECONDITION_FAILED);
            } else {
                log.error(requestId, "Scale for stream {}/{} failed with exception {}", scope, stream, cause);
                response.setStatus(ScaleResponse.ScaleStreamStatus.FAILURE);
            }
        } else {
            log.info(requestId, "scale for stream {}/{} started successfully", scope, stream);
            response.setStatus(ScaleResponse.ScaleStreamStatus.STARTED);
            response.addAllSegments(startScaleResponse.getObject().getNewSegmentsWithRange().entrySet().stream().map(segment -> convert(scope, stream, segment)).collect(Collectors.toList()));
            response.setEpoch(startScaleResponse.getObject().getActiveEpoch());
        }
        return response.build();
    }));
}
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) EpochTransitionOperationExceptions(io.pravega.controller.store.stream.EpochTransitionOperationExceptions) ArrayList(java.util.ArrayList) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent)

Example 2 with ScaleOpEvent

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

the class ControllerEventProcessorTest method testCommitAndStreamProcessorFairness.

@Test(timeout = 30000)
public void testCommitAndStreamProcessorFairness() {
    List<VersionedTransactionData> txnDataList1 = createAndCommitTransactions(3);
    int epoch = txnDataList1.get(0).getEpoch();
    streamStore.startCommitTransactions(SCOPE, STREAM, 100, null, executor).join();
    EventStreamWriterMock<ControllerEvent> requestEventWriter = new EventStreamWriterMock<>();
    streamMetadataTasks.setRequestEventWriter(requestEventWriter);
    CommitRequestHandler commitEventProcessor = new CommitRequestHandler(streamStore, streamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
    StreamRequestHandler streamRequestHandler = new StreamRequestHandler(new AutoScaleTask(streamMetadataTasks, streamStore, executor), new ScaleOperationTask(streamMetadataTasks, streamStore, executor), null, null, null, null, null, null, null, streamStore, null, executor);
    // set some processor name so that the processing gets postponed
    streamStore.createWaitingRequestIfAbsent(SCOPE, STREAM, "test", null, executor).join();
    AssertExtensions.assertFutureThrows("Operation should be disallowed", commitEventProcessor.processEvent(new CommitEvent(SCOPE, STREAM, epoch)), e -> Exceptions.unwrap(e) instanceof StoreException.OperationNotAllowedException);
    streamStore.deleteWaitingRequestConditionally(SCOPE, STREAM, "test1", null, executor).join();
    assertEquals("test", streamStore.getWaitingRequestProcessor(SCOPE, STREAM, null, executor).join());
    // now remove the barrier but change the state so that processing can not happen.
    streamStore.deleteWaitingRequestConditionally(SCOPE, STREAM, "test", null, executor).join();
    assertNull(streamStore.getWaitingRequestProcessor(SCOPE, STREAM, null, executor).join());
    streamStore.setState(SCOPE, STREAM, State.SCALING, null, executor).join();
    AssertExtensions.assertFutureThrows("Operation should be disallowed", commitEventProcessor.processEvent(new CommitEvent(SCOPE, STREAM, epoch)), e -> Exceptions.unwrap(e) instanceof StoreException.OperationNotAllowedException);
    assertEquals(commitEventProcessor.getProcessorName(), streamStore.getWaitingRequestProcessor(SCOPE, STREAM, null, executor).join());
    streamStore.setState(SCOPE, STREAM, State.ACTIVE, null, executor).join();
    // verify that we are able to process if the waiting processor name is same as ours.
    commitEventProcessor.processEvent(new CommitEvent(SCOPE, STREAM, epoch)).join();
    // verify that waiting processor is cleaned up.
    assertNull(streamStore.getWaitingRequestProcessor(SCOPE, STREAM, null, executor).join());
    // now set the state to COMMITTING_TXN and try the same with scaling
    streamStore.setState(SCOPE, STREAM, State.COMMITTING_TXN, null, executor).join();
    // verify that event that does not try to use `processor.withCompletion` runs without contention
    assertTrue(Futures.await(streamRequestHandler.processEvent(new AutoScaleEvent(SCOPE, STREAM, 0L, AutoScaleEvent.UP, 0L, 2, true, 0L))));
    // now same event's processing in face of a barrier should get postponed
    streamStore.createWaitingRequestIfAbsent(SCOPE, STREAM, commitEventProcessor.getProcessorName(), null, executor).join();
    assertTrue(Futures.await(streamRequestHandler.processEvent(new AutoScaleEvent(SCOPE, STREAM, 0L, AutoScaleEvent.UP, 0L, 2, true, 0L))));
    AssertExtensions.assertFutureThrows("Operation should be disallowed", streamRequestHandler.processEvent(new ScaleOpEvent(SCOPE, STREAM, Collections.emptyList(), Collections.emptyList(), false, 0L, 0L)), e -> Exceptions.unwrap(e) instanceof StoreException.OperationNotAllowedException);
    assertEquals(commitEventProcessor.getProcessorName(), streamStore.getWaitingRequestProcessor(SCOPE, STREAM, null, executor).join());
}
Also used : EventStreamWriterMock(io.pravega.controller.mocks.EventStreamWriterMock) VersionedTransactionData(io.pravega.controller.store.stream.VersionedTransactionData) ScaleOperationTask(io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask) CommitRequestHandler(io.pravega.controller.server.eventProcessor.requesthandlers.CommitRequestHandler) AutoScaleEvent(io.pravega.shared.controller.event.AutoScaleEvent) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent) ControllerEvent(io.pravega.shared.controller.event.ControllerEvent) StoreException(io.pravega.controller.store.stream.StoreException) AutoScaleTask(io.pravega.controller.server.eventProcessor.requesthandlers.AutoScaleTask) StreamRequestHandler(io.pravega.controller.server.eventProcessor.requesthandlers.StreamRequestHandler) CommitEvent(io.pravega.shared.controller.event.CommitEvent) Test(org.junit.Test)

Example 3 with ScaleOpEvent

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

the class StreamMetadataTasksTest method truncateStreamTest.

@Test(timeout = 30000)
public void truncateStreamTest() throws Exception {
    final ScalingPolicy policy = ScalingPolicy.fixed(2);
    final StreamConfiguration configuration = StreamConfiguration.builder().scalingPolicy(policy).build();
    streamStorePartialMock.createStream(SCOPE, "test", configuration, System.currentTimeMillis(), null, executor).get();
    streamStorePartialMock.setState(SCOPE, "test", State.ACTIVE, null, executor).get();
    assertNotEquals(0, consumer.getCurrentSegments(SCOPE, "test", 0L).get().size());
    WriterMock requestEventWriter = new WriterMock(streamMetadataTasks, executor);
    streamMetadataTasks.setRequestEventWriter(requestEventWriter);
    List<Map.Entry<Double, Double>> newRanges = new ArrayList<>();
    newRanges.add(new AbstractMap.SimpleEntry<>(0.5, 0.75));
    newRanges.add(new AbstractMap.SimpleEntry<>(0.75, 1.0));
    ScaleResponse scaleOpResult = streamMetadataTasks.manualScale(SCOPE, "test", Collections.singletonList(1L), newRanges, 30, 0L).get();
    assertTrue(scaleOpResult.getStatus().equals(ScaleStreamStatus.STARTED));
    ScaleOperationTask scaleTask = new ScaleOperationTask(streamMetadataTasks, streamStorePartialMock, executor);
    assertTrue(Futures.await(scaleTask.execute((ScaleOpEvent) requestEventWriter.eventQueue.take())));
    // start truncation
    StreamTruncationRecord truncProp = streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor).join().getObject();
    assertFalse(truncProp.isUpdating());
    // 1. happy day test
    // update.. should succeed
    Map<Long, Long> streamCut = new HashMap<>();
    streamCut.put(0L, 1L);
    streamCut.put(1L, 11L);
    CompletableFuture<UpdateStreamStatus.Status> truncateFuture = streamMetadataTasks.truncateStream(SCOPE, "test", streamCut, 0L);
    assertTrue(Futures.await(processEvent(requestEventWriter)));
    assertEquals(UpdateStreamStatus.Status.SUCCESS, truncateFuture.join());
    truncProp = streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor).join().getObject();
    assertTrue(truncProp.getStreamCut().equals(streamCut));
    assertTrue(truncProp.getStreamCut().equals(streamCut));
    // 2. change state to scaling
    streamStorePartialMock.setState(SCOPE, "test", State.SCALING, null, executor).get();
    // call update should fail without posting the event
    long two = NameUtils.computeSegmentId(2, 1);
    long three = NameUtils.computeSegmentId(3, 1);
    Map<Long, Long> streamCut2 = new HashMap<>();
    streamCut2.put(0L, 1L);
    streamCut2.put(two, 1L);
    streamCut2.put(three, 1L);
    streamMetadataTasks.truncateStream(SCOPE, "test", streamCut2, 0L);
    AtomicBoolean loop = new AtomicBoolean(false);
    Futures.loop(() -> !loop.get(), () -> Futures.delayedFuture(() -> streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor), 1000, executor).thenApply(x -> x.getObject().isUpdating()).thenAccept(loop::set), executor).join();
    // event posted, first step performed. now pick the event for processing
    TruncateStreamTask truncateStreamTask = new TruncateStreamTask(streamMetadataTasks, streamStorePartialMock, executor);
    TruncateStreamEvent taken = (TruncateStreamEvent) requestEventWriter.eventQueue.take();
    AssertExtensions.assertFutureThrows("", truncateStreamTask.execute(taken), e -> Exceptions.unwrap(e) instanceof StoreException.OperationNotAllowedException);
    streamStorePartialMock.setState(SCOPE, "test", State.ACTIVE, null, executor).get();
    // now with state = active, process the same event. it should succeed now.
    assertTrue(Futures.await(truncateStreamTask.execute(taken)));
    // 3. multiple back to back updates.
    Map<Long, Long> streamCut3 = new HashMap<>();
    streamCut3.put(0L, 12L);
    streamCut3.put(two, 12L);
    streamCut3.put(three, 12L);
    CompletableFuture<UpdateStreamStatus.Status> truncateOp1 = streamMetadataTasks.truncateStream(SCOPE, "test", streamCut3, 0L);
    // ensure that previous updatestream has posted the event and set status to updating,
    // only then call second updateStream
    AtomicBoolean loop2 = new AtomicBoolean(false);
    Futures.loop(() -> !loop2.get(), () -> streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor).thenApply(x -> x.getObject().isUpdating()).thenAccept(loop2::set), executor).join();
    truncProp = streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor).join().getObject();
    assertTrue(truncProp.getStreamCut().equals(streamCut3) && truncProp.isUpdating());
    // post the second update request. This should fail here itself as previous one has started.
    Map<Long, Long> streamCut4 = new HashMap<>();
    streamCut4.put(0L, 14L);
    streamCut4.put(two, 14L);
    streamCut4.put(three, 14L);
    CompletableFuture<UpdateStreamStatus.Status> truncateOpFuture2 = streamMetadataTasks.truncateStream(SCOPE, "test", streamCut4, 0L);
    assertEquals(UpdateStreamStatus.Status.FAILURE, truncateOpFuture2.join());
    // process event
    assertTrue(Futures.await(processEvent(requestEventWriter)));
    // verify that first request for update also completes with success.
    assertEquals(UpdateStreamStatus.Status.SUCCESS, truncateOp1.join());
    truncProp = streamStorePartialMock.getTruncationRecord(SCOPE, "test", null, executor).join().getObject();
    assertTrue(truncProp.getStreamCut().equals(streamCut3) && !truncProp.isUpdating());
    streamStorePartialMock.setState(SCOPE, "test", State.TRUNCATING, null, executor).join();
    TruncateStreamEvent event = new TruncateStreamEvent(SCOPE, "test", System.nanoTime());
    assertTrue(Futures.await(truncateStreamTask.execute(event)));
    // execute the event again. It should complete without doing anything.
    truncateStreamTask.execute(event).join();
    assertEquals(State.ACTIVE, streamStorePartialMock.getState(SCOPE, "test", true, null, executor).join());
    doReturn(CompletableFuture.completedFuture(true)).when(streamStorePartialMock).isScopeSealed(anyString(), any(), any());
    CompletableFuture<CreateStreamResponse> streamResponse = streamStorePartialMock.createStream(SCOPE, "test", configuration, System.currentTimeMillis(), null, executor);
    CreateStreamResponse.CreateStatus s = streamResponse.get().getStatus();
    assertEquals(CreateStreamResponse.CreateStatus.EXISTS_ACTIVE, streamResponse.get().getStatus());
}
Also used : UpdateStreamEvent(io.pravega.shared.controller.event.UpdateStreamEvent) Arrays(java.util.Arrays) StreamCut(io.pravega.client.stream.StreamCut) EventStreamWriter(io.pravega.client.stream.EventStreamWriter) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Cleanup(lombok.Cleanup) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) AbstractStreamMetadataStore(io.pravega.controller.store.stream.AbstractStreamMetadataStore) StoreException(io.pravega.controller.store.stream.StoreException) AutoScaleTask(io.pravega.controller.server.eventProcessor.requesthandlers.AutoScaleTask) TaskMetadataStore(io.pravega.controller.store.task.TaskMetadataStore) Duration(java.time.Duration) Map(java.util.Map) Mockito.doAnswer(org.mockito.Mockito.doAnswer) RGStreamCutRecord(io.pravega.shared.controller.event.RGStreamCutRecord) LockFailedException(io.pravega.controller.store.task.LockFailedException) Mockito.doReturn(org.mockito.Mockito.doReturn) ReaderGroupConfig(io.pravega.client.stream.ReaderGroupConfig) ControllerEventStreamWriterMock(io.pravega.controller.mocks.ControllerEventStreamWriterMock) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) StreamMetadataStoreTestHelper(io.pravega.controller.store.stream.StreamMetadataStoreTestHelper) DeleteStreamEvent(io.pravega.shared.controller.event.DeleteStreamEvent) RequestTracker(io.pravega.common.tracing.RequestTracker) ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) ControllerEvent(io.pravega.shared.controller.event.ControllerEvent) KVTableMetadataStore(io.pravega.controller.store.kvtable.KVTableMetadataStore) Assert.assertFalse(org.junit.Assert.assertFalse) CreateReaderGroupTask(io.pravega.controller.server.eventProcessor.requesthandlers.CreateReaderGroupTask) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) EventStreamWriterMock(io.pravega.controller.mocks.EventStreamWriterMock) Futures(io.pravega.common.concurrent.Futures) GrpcAuthHelper(io.pravega.controller.server.security.auth.GrpcAuthHelper) Mockito.mock(org.mockito.Mockito.mock) CuratorFrameworkFactory(org.apache.curator.framework.CuratorFrameworkFactory) Mockito.doCallRealMethod(org.mockito.Mockito.doCallRealMethod) StreamMetrics(io.pravega.controller.metrics.StreamMetrics) StreamStoreFactory(io.pravega.controller.store.stream.StreamStoreFactory) TransactionMetrics(io.pravega.controller.metrics.TransactionMetrics) NameUtils.computeSegmentId(io.pravega.shared.NameUtils.computeSegmentId) ConnectionFactory(io.pravega.client.connection.impl.ConnectionFactory) Mock(org.mockito.Mock) RetentionPolicy(io.pravega.client.stream.RetentionPolicy) Exceptions(io.pravega.common.Exceptions) TruncateStreamEvent(io.pravega.shared.controller.event.TruncateStreamEvent) Mockito.spy(org.mockito.Mockito.spy) Supplier(java.util.function.Supplier) UpdateSubscriberStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateSubscriberStatus) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) TestingServerStarter(io.pravega.test.common.TestingServerStarter) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TestingServer(org.apache.curator.test.TestingServer) EventHelper(io.pravega.controller.task.EventHelper) UpdateReaderGroupTask(io.pravega.controller.server.eventProcessor.requesthandlers.UpdateReaderGroupTask) CreateReaderGroupEvent(io.pravega.shared.controller.event.CreateReaderGroupEvent) Before(org.junit.Before) SegmentHelperMock(io.pravega.controller.mocks.SegmentHelperMock) EventHelperMock(io.pravega.controller.mocks.EventHelperMock) Assert.assertTrue(org.junit.Assert.assertTrue) CreateStreamResponse(io.pravega.controller.store.stream.CreateStreamResponse) Test(org.junit.Test) TableMetadataTasks(io.pravega.controller.task.KeyValueTable.TableMetadataTasks) Assert.assertNotEquals(org.junit.Assert.assertNotEquals) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) TaskStoreFactory(io.pravega.controller.store.task.TaskStoreFactory) Assert.assertNull(org.junit.Assert.assertNull) DeleteStreamTask(io.pravega.controller.server.eventProcessor.requesthandlers.DeleteStreamTask) StreamRequestHandler(io.pravega.controller.server.eventProcessor.requesthandlers.StreamRequestHandler) DeleteReaderGroupStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteReaderGroupStatus) Mockito.reset(org.mockito.Mockito.reset) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) Assert.assertEquals(org.junit.Assert.assertEquals) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CommitEvent(io.pravega.shared.controller.event.CommitEvent) AssertExtensions(io.pravega.test.common.AssertExtensions) DeleteReaderGroupEvent(io.pravega.shared.controller.event.DeleteReaderGroupEvent) TimeoutException(java.util.concurrent.TimeoutException) SealStreamEvent(io.pravega.shared.controller.event.SealStreamEvent) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) Stream(io.pravega.client.stream.Stream) After(org.junit.After) SubscribersResponse(io.pravega.controller.stream.api.grpc.v1.Controller.SubscribersResponse) Controller(io.pravega.controller.stream.api.grpc.v1.Controller) TaskExceptions(io.pravega.controller.server.eventProcessor.requesthandlers.TaskExceptions) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) ImmutableSet(com.google.common.collect.ImmutableSet) SealStreamTask(io.pravega.controller.server.eventProcessor.requesthandlers.SealStreamTask) ImmutableMap(com.google.common.collect.ImmutableMap) AssertExtensions.assertFutureThrows(io.pravega.test.common.AssertExtensions.assertFutureThrows) DeleteScopeEvent(io.pravega.shared.controller.event.DeleteScopeEvent) CompletionException(java.util.concurrent.CompletionException) ScaleStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse.ScaleStreamStatus) UUID(java.util.UUID) ScaleOperationTask(io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) AbstractClientFactoryImpl(io.pravega.client.stream.impl.AbstractClientFactoryImpl) List(java.util.List) CuratorFramework(org.apache.curator.framework.CuratorFramework) Config(io.pravega.controller.util.Config) UpdateStreamTask(io.pravega.controller.server.eventProcessor.requesthandlers.UpdateStreamTask) TxnStatus(io.pravega.controller.store.stream.TxnStatus) VersionedTransactionData(io.pravega.controller.store.stream.VersionedTransactionData) Optional(java.util.Optional) DeleteScopeTask(io.pravega.controller.server.eventProcessor.requesthandlers.DeleteScopeTask) TruncateStreamTask(io.pravega.controller.server.eventProcessor.requesthandlers.TruncateStreamTask) NotImplementedException(org.apache.commons.lang3.NotImplementedException) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) OperationContext(io.pravega.controller.store.stream.OperationContext) Segment(io.pravega.client.segment.impl.Segment) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) Getter(lombok.Getter) SegmentHelper(io.pravega.controller.server.SegmentHelper) ModelHelper(io.pravega.client.control.impl.ModelHelper) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) BucketStore(io.pravega.controller.store.stream.BucketStore) AbortEvent(io.pravega.shared.controller.event.AbortEvent) ExponentialBackoffRetry(org.apache.curator.retry.ExponentialBackoffRetry) StreamCutImpl(io.pravega.client.stream.impl.StreamCutImpl) LinkedList(java.util.LinkedList) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) SocketConnectionFactoryImpl(io.pravega.client.connection.impl.SocketConnectionFactoryImpl) ScaleResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse) EventWriterConfig(io.pravega.client.stream.EventWriterConfig) ControllerService(io.pravega.controller.server.ControllerService) NameUtils(io.pravega.shared.NameUtils) Assert.assertNotNull(org.junit.Assert.assertNotNull) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) AbstractMap(java.util.AbstractMap) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) UpdateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateStreamStatus) Data(lombok.Data) State(io.pravega.controller.store.stream.State) ExecutorServiceHelpers(io.pravega.common.concurrent.ExecutorServiceHelpers) UpdateReaderGroupEvent(io.pravega.shared.controller.event.UpdateReaderGroupEvent) DeleteReaderGroupTask(io.pravega.controller.server.eventProcessor.requesthandlers.DeleteReaderGroupTask) ReaderGroupConfigResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ReaderGroupConfigResponse) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent) Collections(java.util.Collections) ClientConfig(io.pravega.client.ClientConfig) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractMap(java.util.AbstractMap) TruncateStreamEvent(io.pravega.shared.controller.event.TruncateStreamEvent) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) ControllerEventStreamWriterMock(io.pravega.controller.mocks.ControllerEventStreamWriterMock) EventStreamWriterMock(io.pravega.controller.mocks.EventStreamWriterMock) UpdateSubscriberStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateSubscriberStatus) DeleteReaderGroupStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteReaderGroupStatus) ScaleStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse.ScaleStreamStatus) TxnStatus(io.pravega.controller.store.stream.TxnStatus) UpdateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateStreamStatus) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) CreateStreamResponse(io.pravega.controller.store.stream.CreateStreamResponse) ScaleResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse) ScaleOperationTask(io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask) StoreException(io.pravega.controller.store.stream.StoreException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) TruncateStreamTask(io.pravega.controller.server.eventProcessor.requesthandlers.TruncateStreamTask) Test(org.junit.Test)

Example 4 with ScaleOpEvent

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

the class PravegaTablesScaleRequestHandlerTest method testEpochMigration.

@Test(timeout = 30000)
public void testEpochMigration() throws ExecutionException, InterruptedException {
    final String scope = "scopeEpoch";
    streamStore.createScope(scope, null, executor).get();
    final String testStream = "streamEpoch";
    final String epoch0Key = "epochRecord-0";
    long creationTime = System.currentTimeMillis();
    StreamSegmentRecord segRecord = new StreamSegmentRecord(0, 0, creationTime, 0.0, 1.0);
    EpochRecord firstEpochInOldFormat = new EpochRecord(0, 0, ImmutableList.of(segRecord), creationTime, EpochRecord.DEFAULT_COUNT_VALUE, EpochRecord.DEFAULT_COUNT_VALUE);
    VersionedMetadata<EpochRecord> expectedEpochRecord = new VersionedMetadata<>(firstEpochInOldFormat, new Version.IntVersion(0));
    doReturn(CompletableFuture.completedFuture(expectedEpochRecord)).when(storeHelper).getCachedOrLoad(anyString(), eq(epoch0Key), any(), anyLong(), anyLong());
    ScaleOperationTask scaleRequestHandler = new ScaleOperationTask(streamMetadataTasks, streamStore, executor);
    StreamConfiguration config = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(1, 2, 1)).build();
    streamStore.createStream(scope, testStream, config, System.currentTimeMillis(), null, executor).join();
    streamStore.setState(scope, testStream, State.ACTIVE, null, executor).join();
    assertEquals(firstEpochInOldFormat, streamStore.getEpoch(scope, testStream, 0, null, executor).join());
    ArrayList<Map.Entry<Double, Double>> newRange = new ArrayList<>();
    newRange.add(new AbstractMap.SimpleEntry<>(0.0, 1.0));
    // start with manual scale
    ScaleOpEvent event = new ScaleOpEvent(scope, testStream, Lists.newArrayList(0L), newRange, true, System.currentTimeMillis(), System.currentTimeMillis());
    streamStore.submitScale(scope, testStream, Lists.newArrayList(0L), new ArrayList<>(newRange), System.currentTimeMillis(), null, null, executor).join();
    // perform scaling
    scaleRequestHandler.execute(event).join();
    assertEquals(State.ACTIVE, streamStore.getState(scope, testStream, true, null, executor).join());
    assertEquals(1, streamStore.getActiveEpoch(scope, testStream, null, true, executor).join().getEpoch());
}
Also used : EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) ArrayList(java.util.ArrayList) Mockito.anyString(org.mockito.Mockito.anyString) ScaleOperationTask(io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent) AbstractMap(java.util.AbstractMap) StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) Version(io.pravega.controller.store.Version) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) Test(org.junit.Test)

Example 5 with ScaleOpEvent

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

the class ScaleRequestHandlerTest method concurrentIdenticalScaleRun.

private void concurrentIdenticalScaleRun(String stream, String func, boolean isManual, Predicate<Throwable> firstExceptionPredicate, boolean expectFailureOnSecondJob, Predicate<Throwable> secondExceptionPredicate, Map<String, Integer> invocationCount) throws Exception {
    StreamMetadataStore streamStore1 = getStore();
    StreamMetadataStore streamStore1Spied = spy(getStore());
    StreamConfiguration config = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(1, 2, 1)).build();
    streamStore1.createStream(scope, stream, config, System.currentTimeMillis(), null, executor).join();
    streamStore1.setState(scope, stream, State.ACTIVE, null, executor).join();
    CompletableFuture<Void> wait = new CompletableFuture<>();
    CompletableFuture<Void> signal = new CompletableFuture<>();
    ScaleOpEvent event = new ScaleOpEvent(scope, stream, Lists.newArrayList(0L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.0, 1.0)), isManual, System.currentTimeMillis(), System.currentTimeMillis());
    if (isManual) {
        streamStore1.submitScale(scope, stream, Lists.newArrayList(0L), Lists.newArrayList(new AbstractMap.SimpleEntry<>(0.0, 1.0)), System.currentTimeMillis(), null, null, executor).join();
    }
    StreamMetadataStore streamStore2 = getStore();
    ScaleOperationTask scaleRequestHandler1 = new ScaleOperationTask(streamMetadataTasks, streamStore1Spied, executor);
    ScaleOperationTask scaleRequestHandler2 = new ScaleOperationTask(streamMetadataTasks, streamStore2, executor);
    setMockLatch(streamStore1, streamStore1Spied, func, signal, wait);
    // the processing will stall at start scale
    CompletableFuture<Void> future1 = CompletableFuture.completedFuture(null).thenComposeAsync(v -> scaleRequestHandler1.execute(event), executor);
    signal.join();
    // let this run to completion. this should succeed
    if (!expectFailureOnSecondJob) {
        scaleRequestHandler2.execute(event).join();
    } else {
        AssertExtensions.assertSuppliedFutureThrows("second job should fail", () -> scaleRequestHandler2.execute(event), secondExceptionPredicate);
    }
    // verify that scale is complete
    // now complete wait latch.
    wait.complete(null);
    AssertExtensions.assertSuppliedFutureThrows("first scale should fail", () -> future1, firstExceptionPredicate);
    verify(streamStore1Spied, times(invocationCount.get("startScale"))).startScale(anyString(), anyString(), anyBoolean(), any(), any(), any(), any());
    verify(streamStore1Spied, times(invocationCount.get("scaleCreateNewEpochs"))).scaleCreateNewEpochs(anyString(), anyString(), any(), any(), any());
    verify(streamStore1Spied, times(invocationCount.get("scaleSegmentsSealed"))).scaleSegmentsSealed(anyString(), anyString(), any(), any(), any(), any());
    verify(streamStore1Spied, times(invocationCount.get("completeScale"))).completeScale(anyString(), anyString(), any(), any(), any());
    verify(streamStore1Spied, times(invocationCount.get("updateVersionedState"))).updateVersionedState(anyString(), anyString(), any(), any(), any(), any());
    // validate scale done
    VersionedMetadata<EpochTransitionRecord> versioned = streamStore1.getEpochTransition(scope, stream, null, executor).join();
    assertEquals(EpochTransitionRecord.EMPTY, versioned.getObject());
    assertEquals(2, getVersionNumber(versioned));
    assertEquals(1, streamStore1.getActiveEpoch(scope, stream, null, true, executor).join().getEpoch());
    assertEquals(State.ACTIVE, streamStore1.getState(scope, stream, true, null, executor).join());
    streamStore1.close();
    streamStore2.close();
}
Also used : AbstractMap(java.util.AbstractMap) CompletableFuture(java.util.concurrent.CompletableFuture) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) ScaleOperationTask(io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent)

Aggregations

ScaleOpEvent (io.pravega.shared.controller.event.ScaleOpEvent)19 ScaleOperationTask (io.pravega.controller.server.eventProcessor.requesthandlers.ScaleOperationTask)17 Test (org.junit.Test)15 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)14 AbstractMap (java.util.AbstractMap)14 EpochRecord (io.pravega.controller.store.stream.records.EpochRecord)11 StreamRequestHandler (io.pravega.controller.server.eventProcessor.requesthandlers.StreamRequestHandler)10 VersionedTransactionData (io.pravega.controller.store.stream.VersionedTransactionData)10 CommitEvent (io.pravega.shared.controller.event.CommitEvent)10 UUID (java.util.UUID)10 CompletableFuture (java.util.concurrent.CompletableFuture)9 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)9 CommitRequestHandler (io.pravega.controller.server.eventProcessor.requesthandlers.CommitRequestHandler)8 State (io.pravega.controller.store.stream.State)8 StoreException (io.pravega.controller.store.stream.StoreException)8 StreamMetadataStore (io.pravega.controller.store.stream.StreamMetadataStore)8 ControllerEvent (io.pravega.shared.controller.event.ControllerEvent)8 ArrayList (java.util.ArrayList)8 AutoScaleTask (io.pravega.controller.server.eventProcessor.requesthandlers.AutoScaleTask)7 TxnStatus (io.pravega.controller.store.stream.TxnStatus)7