use of io.pravega.client.stream.impl.StreamSegments in project pravega by pravega.
the class ControllerFailoverTest method failoverTest.
@Test(timeout = 180000)
public void failoverTest() throws InterruptedException, ExecutionException {
String scope = "testFailoverScope" + RandomStringUtils.randomAlphabetic(5);
String stream = "testFailoverStream" + RandomStringUtils.randomAlphabetic(5);
int initialSegments = 2;
List<Integer> segmentsToSeal = Collections.singletonList(0);
Map<Double, Double> newRangesToCreate = new HashMap<>();
newRangesToCreate.put(0.0, 0.25);
newRangesToCreate.put(0.25, 0.5);
long lease = 29000;
long maxExecutionTime = 60000;
long scaleGracePeriod = 30000;
// Connect with first controller instance.
final Controller controller1 = new ControllerImpl(ControllerImplConfig.builder().clientConfig(ClientConfig.builder().controllerURI(controllerURIDirect).build()).build(), EXECUTOR_SERVICE);
// Create scope, stream, and a transaction with high timeout value.
controller1.createScope(scope).join();
log.info("Scope {} created successfully", scope);
createStream(controller1, scope, stream, ScalingPolicy.fixed(initialSegments));
log.info("Stream {}/{} created successfully", scope, stream);
long txnCreationTimestamp = System.nanoTime();
StreamImpl stream1 = new StreamImpl(scope, stream);
TxnSegments txnSegments = controller1.createTransaction(stream1, lease, scaleGracePeriod).join();
log.info("Transaction {} created successfully, beginTime={}", txnSegments.getTxnId(), txnCreationTimestamp);
// Initiate scale operation. It will block until ongoing transaction is complete.
controller1.startScale(stream1, segmentsToSeal, newRangesToCreate).join();
// Ensure that scale is not yet done.
boolean scaleStatus = controller1.checkScaleStatus(stream1, 0).join();
log.info("Status of scale operation isDone={}", scaleStatus);
Assert.assertTrue(!scaleStatus);
// Now stop the controller instance executing scale operation.
Futures.getAndHandleExceptions(controllerService1.scaleService(1), ExecutionException::new);
log.info("Successfully stopped one instance of controller service");
List<URI> conUris = controllerService1.getServiceDetails();
// Fetch all the RPC endpoints and construct the client URIs.
final List<String> uris = conUris.stream().filter(uri -> Utils.DOCKER_BASED ? uri.getPort() == Utils.DOCKER_CONTROLLER_PORT : uri.getPort() == Utils.MARATHON_CONTROLLER_PORT).map(URI::getAuthority).collect(Collectors.toList());
controllerURIDirect = URI.create("tcp://" + String.join(",", uris));
log.info("Controller Service direct URI: {}", controllerURIDirect);
// Connect to another controller instance.
final Controller controller2 = new ControllerImpl(ControllerImplConfig.builder().clientConfig(ClientConfig.builder().controllerURI(controllerURIDirect).build()).build(), EXECUTOR_SERVICE);
// Fetch status of transaction.
log.info("Fetching status of transaction {}, time elapsed since its creation={}", txnSegments.getTxnId(), System.nanoTime() - txnCreationTimestamp);
Transaction.Status status = controller2.checkTransactionStatus(stream1, txnSegments.getTxnId()).join();
log.info("Transaction {} status={}", txnSegments.getTxnId(), status);
if (status == Transaction.Status.OPEN) {
// Abort the ongoing transaction.
log.info("Trying to abort transaction {}, by sending request to controller at {}", txnSegments.getTxnId(), controllerURIDirect);
controller2.abortTransaction(stream1, txnSegments.getTxnId()).join();
}
// Note: if scale does not complete within desired time, test will timeout.
while (!scaleStatus) {
scaleStatus = controller2.checkScaleStatus(stream1, 0).join();
Thread.sleep(30000);
}
// Ensure that the stream has 3 segments now.
log.info("Checking whether scale operation succeeded by fetching current segments");
StreamSegments streamSegments = controller2.getCurrentSegments(scope, stream).join();
log.info("Current segment count=", streamSegments.getSegments().size());
Assert.assertEquals(initialSegments - segmentsToSeal.size() + newRangesToCreate.size(), streamSegments.getSegments().size());
}
Aggregations