@Test public void eventWriterInitializationTest() throws Exception { final ScalingPolicy policy = ScalingPolicy.fixed(1); 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(); AssertExtensions.assertThrows("", () -> streamMetadataTasks.manualScale(SCOPE, "test", Collections.singletonList(0L), Arrays.asList(), 30, null).get(), e -> e instanceof TaskExceptions.ProcessingDisabledException); streamMetadataTasks.setRequestEventWriter(new ControllerEventStreamWriterMock(streamRequestHandler, executor)); List<AbstractMap.SimpleEntry<Double, Double>> newRanges = new ArrayList<>(); newRanges.add(new AbstractMap.SimpleEntry<>(0.0, 0.5)); newRanges.add(new AbstractMap.SimpleEntry<>(0.5, 1.0)); ScaleResponse scaleOpResult = streamMetadataTasks.manualScale(SCOPE, "test", Collections.singletonList(0L), newRanges, 30, null).get(); assertEquals(ScaleStreamStatus.STARTED, scaleOpResult.getStatus()); Controller.ScaleStatusResponse scaleStatusResult = streamMetadataTasks.checkScale(SCOPE, "UNKNOWN", 0, null).get(); assertEquals(Controller.ScaleStatusResponse.ScaleStatus.INVALID_INPUT, scaleStatusResult.getStatus()); scaleStatusResult = streamMetadataTasks.checkScale("UNKNOWN", "test", 0, null).get(); assertEquals(Controller.ScaleStatusResponse.ScaleStatus.INVALID_INPUT, scaleStatusResult.getStatus()); scaleStatusResult = streamMetadataTasks.checkScale(SCOPE, "test", 5, null).get(); assertEquals(Controller.ScaleStatusResponse.ScaleStatus.INVALID_INPUT, scaleStatusResult.getStatus()); }
newRanges, 30, null).get(); assertEquals(ScaleStreamStatus.STARTED, scaleOpResult.getStatus()); OperationContext context = streamStorePartialMock.createContext(SCOPE, "test"); assertEquals(streamStorePartialMock.getState(SCOPE, "test", false, context, executor).get(), State.ACTIVE);
@Override public CancellableRequest<Boolean> scaleStream(final Stream stream, final List<Long> sealedSegments, final Map<Double, Double> newKeyRanges, final ScheduledExecutorService executor) { CancellableRequest<Boolean> cancellableRequest = new CancellableRequest<>(); startScaleInternal(stream, sealedSegments, newKeyRanges) .whenComplete((startScaleResponse, e) -> { if (e != null) { cancellableRequest.start(() -> Futures.failedFuture(e), any -> true, executor); } else { final boolean started = startScaleResponse.getStatus().equals(ScaleResponse.ScaleStreamStatus.STARTED); cancellableRequest.start(() -> { if (started) { return checkScaleStatus(stream, startScaleResponse.getEpoch()); } else { return CompletableFuture.completedFuture(false); } }, isDone -> !started || isDone, executor); } }); return cancellableRequest; }
ScaleResponse scaleOpResult = streamMetadataTasks.manualScale(SCOPE, "test", Collections.singletonList(1L), newRanges, 30, null).get(); assertTrue(scaleOpResult.getStatus().equals(ScaleStreamStatus.STARTED));
Controller.ScaleResponse scaleStatus = consumer.scale(SCOPE, STREAM, Arrays.asList(1L), keyRanges, start + 20) .get(); assertEquals(Controller.ScaleResponse.ScaleStreamStatus.STARTED, scaleStatus.getStatus()); AtomicBoolean done = new AtomicBoolean(false); Futures.loop(() -> !done.get(), () -> consumer.checkScale(SCOPE, STREAM, scaleStatus.getEpoch())
this.controllerService.scale(scaleRequest, result2); final ScaleResponse scaleResponse = result2.get(); Assert.assertEquals(ScaleResponse.ScaleStreamStatus.STARTED, scaleResponse.getStatus());
@Test(timeout = 30000) public void sealStreamTest() throws Exception { assertNotEquals(0, consumer.getCurrentSegments(SCOPE, stream1).get().size()); WriterMock requestEventWriter = new WriterMock(streamMetadataTasks, executor); streamMetadataTasks.setRequestEventWriter(requestEventWriter); //seal a stream. CompletableFuture<UpdateStreamStatus.Status> sealOperationResult = streamMetadataTasks.sealStream(SCOPE, stream1, null); assertTrue(Futures.await(processEvent(requestEventWriter))); assertEquals(UpdateStreamStatus.Status.SUCCESS, sealOperationResult.get()); //a sealed stream should have zero active/current segments assertEquals(0, consumer.getCurrentSegments(SCOPE, stream1).get().size()); assertTrue(streamStorePartialMock.isSealed(SCOPE, stream1, null, executor).get()); //reseal a sealed stream. assertEquals(UpdateStreamStatus.Status.SUCCESS, streamMetadataTasks.sealStream(SCOPE, stream1, null).get()); assertTrue(Futures.await(processEvent(requestEventWriter))); //scale operation on the sealed stream. AbstractMap.SimpleEntry<Double, Double> segment3 = new AbstractMap.SimpleEntry<>(0.0, 0.2); AbstractMap.SimpleEntry<Double, Double> segment4 = new AbstractMap.SimpleEntry<>(0.2, 0.4); AbstractMap.SimpleEntry<Double, Double> segment5 = new AbstractMap.SimpleEntry<>(0.4, 0.5); ScaleResponse scaleOpResult = streamMetadataTasks.manualScale(SCOPE, stream1, Collections.singletonList(0L), Arrays.asList(segment3, segment4, segment5), 30, null).get(); // scaling operation fails once a stream is sealed. assertEquals(ScaleStreamStatus.FAILURE, scaleOpResult.getStatus()); AssertExtensions.assertFutureThrows("Scale should not be allowed as stream is already sealed", streamStorePartialMock.submitScale(SCOPE, stream1, Collections.singletonList(0L), Arrays.asList(segment3, segment4, segment5), 30, null, null, executor), e -> Exceptions.unwrap(e) instanceof StoreException.IllegalStateException); }
@Override public CompletableFuture<Boolean> startScale(final Stream stream, final List<Long> sealedSegments, final Map<Double, Double> newKeyRanges) { return startScaleInternal(stream, sealedSegments, newKeyRanges) .thenApply(x -> { switch (x.getStatus()) { case FAILURE: throw new ControllerFailureException("Failed to scale stream: " + stream); case PRECONDITION_FAILED: return false; case STARTED: return true; default: throw new ControllerFailureException("Unknown return status scaling stream " + stream + " " + x.getStatus()); } }); }
private Boolean handleScaleResponse(Stream stream, ScaleResponse response, long requestId) { switch (response.getStatus()) { case FAILURE: log.warn(requestId, "Failed to scale stream: {}", stream.getStreamName()); throw new ControllerFailureException("Failed to scale stream: " + stream); case PRECONDITION_FAILED: log.warn(requestId, "Precondition failed for scale stream: {}", stream.getStreamName()); return false; case STARTED: log.info(requestId, "Successfully started scale stream: {}", stream.getStreamName()); return true; case UNRECOGNIZED: default: throw new ControllerFailureException("Unknown return status scaling stream " + stream + " " + response.getStatus()); } }