use of io.strimzi.api.kafka.model.KafkaRebalanceSpecBuilder in project strimzi by strimzi.
the class KafkaRebalanceStatusTest method testProcessProposal.
@Test
public void testProcessProposal() {
JsonObject proposal = buildOptimizationProposal();
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, new KafkaRebalanceSpecBuilder().build());
KafkaRebalanceAssemblyOperator.MapAndStatus<ConfigMap, Map<String, Object>> output = KafkaRebalanceAssemblyOperator.processOptimizationProposal(kr, proposal);
Map<String, String> brokerMap = output.getLoadMap().getData();
try {
ObjectMapper mapper = new ObjectMapper();
Map<String, LinkedHashMap<String, String>> brokerLoadMap = mapper.readValue(brokerMap.get(KafkaRebalanceAssemblyOperator.BROKER_LOAD_KEY), LinkedHashMap.class);
assertThat(brokerMap, hasKey(KafkaRebalanceAssemblyOperator.BROKER_LOAD_KEY));
LinkedHashMap<String, LinkedHashMap<String, Object>> m = (LinkedHashMap) brokerLoadMap.get("1");
assertThat(m, hasKey(CruiseControlLoadParameters.CPU_PERCENTAGE.getKafkaRebalanceStatusKey()));
assertThat((Double) m.get("cpuPercentage").get("before"), is(10.0));
assertThat((Double) m.get("cpuPercentage").get("after"), is(20.0));
assertThat((Double) m.get("cpuPercentage").get("diff"), is(10.0));
assertThat(m, hasKey(CruiseControlLoadParameters.REPLICAS.getKafkaRebalanceStatusKey()));
assertThat((Integer) m.get("replicas").get("before"), is(10));
assertThat((Integer) m.get("replicas").get("after"), is(5));
assertThat((Integer) m.get("replicas").get("diff"), is(-5));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
use of io.strimzi.api.kafka.model.KafkaRebalanceSpecBuilder in project strimzi by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testNewWithMissingHardGoals.
/**
* Tests the transition from 'New' to 'NotReady' due to "missing hard goals" error
*
* 1. A new KafkaRebalance resource is created with some specified not hard goals; it is in the 'New' state
* 2. The operator requests a rebalance proposal through the Cruise Control REST API
* 3. The operator gets a "missing hard goals" error instead of a proposal
* 4. The KafkaRebalance resource moves to the 'NotReady' state
*/
@Test
public void testNewWithMissingHardGoals(VertxTestContext context) throws IOException, URISyntaxException {
// Setup the rebalance endpoint to get error about hard goals
MockCruiseControl.setupCCRebalanceBadGoalsError(ccServer);
KafkaRebalanceSpec kafkaRebalanceSpec = new KafkaRebalanceSpecBuilder().withGoals("DiskCapacityGoal", "CpuCapacityGoal").build();
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, kafkaRebalanceSpec);
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
// the Kafka cluster isn't deployed in the namespace
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient);
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> context.verify(() -> {
// the resource moved from New to NotReady due to the error
KafkaRebalance kr1 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
assertThat(kr1, StateMatchers.hasState());
Condition condition = kcrao.rebalanceStateCondition(kr1.getStatus());
assertThat(condition, StateMatchers.hasStateInCondition(KafkaRebalanceState.NotReady, CruiseControlRestException.class, "Error processing POST request '/rebalance' due to: " + "'java.lang.IllegalArgumentException: Missing hard goals [NetworkInboundCapacityGoal, DiskCapacityGoal, RackAwareGoal, NetworkOutboundCapacityGoal, CpuCapacityGoal, ReplicaCapacityGoal] " + "in the provided goals: [RackAwareGoal, ReplicaCapacityGoal]. " + "Add skip_hard_goal_check=true parameter to ignore this sanity check.'."));
checkpoint.flag();
})));
}
use of io.strimzi.api.kafka.model.KafkaRebalanceSpecBuilder in project strimzi by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testNewToProposalReadyToRebalancingToReadyThenRefreshRebalance.
/**
* Tests the transition from 'New' to 'ProposalReady'
* The rebalance proposal is approved and the resource moves to 'Rebalancing' and finally to 'Ready'
* Then the Ready KafkaRebalance is refreshed and a moved to 'ProposalReady' again.
*
* 1. A new KafkaRebalance resource is created; it is in the 'New' state
* 2. The operator requests a rebalance proposal through the Cruise Control REST API
* 3. The rebalance proposal is ready on the first call
* 4. The KafkaRebalance resource transitions to the 'ProposalReady' state
* 5. The KafkaRebalance resource is annotated with 'strimzi.io/rebalance=approve'
* 6. The operator requests the rebalance operation through the Cruise Control REST API
* 7. The rebalance operation is not done immediately; the operator starts polling the Cruise Control REST API
* 8. The KafkaRebalance resource moves to the 'Rebalancing' state
* 9. The rebalance operation is done
* 10. The KafkaRebalance resource moves to the 'Ready' state
* 11. The KafkaRebalance resource is annotated with 'strimzi.io/rebalance=refresh'
* 12. The KafkaRebalance resource moves to the 'ProposalReady' state
*/
@Test
public void testNewToProposalReadyToRebalancingToReadyThenRefreshRebalance(VertxTestContext context) throws IOException, URISyntaxException {
// Setup the rebalance and user tasks endpoints with the number of pending calls before a response is received.
MockCruiseControl.setupCCRebalanceResponse(ccServer, 0);
MockCruiseControl.setupCCUserTasksResponseNoGoals(ccServer, 0, 0);
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, new KafkaRebalanceSpecBuilder().build());
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient);
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.ProposalReady))).compose(v -> {
// apply the "approve" annotation to the resource in the ProposalReady state
KafkaRebalance approvedKr = annotate(kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceAnnotation.approve);
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), approvedKr);
}).onComplete(context.succeeding(v -> {
// the resource moved from ProposalReady to Rebalancing on approval
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.Rebalancing);
})).compose(v -> {
// trigger another reconcile to process the Rebalancing state
KafkaRebalance kr4 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr4);
}).onComplete(context.succeeding(v -> {
// the resource moved from Rebalancing to Ready
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.Ready);
})).compose(v -> {
// apply the "refresh" annotation to the resource in the ProposalReady state
KafkaRebalance refreshKr = annotate(kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceAnnotation.refresh);
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), refreshKr);
}).onComplete(context.succeeding(v -> {
// the resource moved from Ready to PropsalPending
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.ProposalReady);
checkpoint.flag();
}));
}
use of io.strimzi.api.kafka.model.KafkaRebalanceSpecBuilder in project strimzi by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testNewToPendingProposalToStoppedRebalance.
/**
* Tests the transition from 'New' to 'PendingProposal' and then 'Stopped' (via annotation)
*
* 1. A new KafkaRebalance resource is created; it is in the 'New' state
* 2. The operator requests a rebalance proposal via the Cruise Control REST API
* 3. The rebalance proposal is not ready yet; the operator starts polling the Cruise Control REST API
* 4. The KafkaRebalance resource transitions to the 'PendingProposal' state
* 6. While the operator is waiting for the proposal, the KafkaRebalance resource is annotated with strimzi.io/rebalance=stop
* 7. The operator stops polling the Cruise Control REST API
* 8. The KafkaRebalance resource moves to 'Stopped' state
*/
@Test
public void testNewToPendingProposalToStoppedRebalance(VertxTestContext context) throws IOException, URISyntaxException {
// Setup the rebalance endpoint with the number of pending calls before a response is received.
MockCruiseControl.setupCCRebalanceResponse(ccServer, 5);
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, new KafkaRebalanceSpecBuilder().build());
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient, new Runnable() {
int count = 0;
@Override
public void run() {
if (++count == 4) {
// after a while, apply the "stop" annotation to the resource in the PendingProposal state
annotate(kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceAnnotation.stop);
}
return;
}
});
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> {
// the resource moved from New to PendingProposal (due to the configured Mock server pending calls)
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.PendingProposal);
})).compose(v -> {
// trigger another reconcile to process the PendingProposal state
KafkaRebalance kr1 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr1);
}).onComplete(context.succeeding(v -> {
// the resource moved from ProposalPending to Stopped
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.Stopped);
checkpoint.flag();
}));
}
use of io.strimzi.api.kafka.model.KafkaRebalanceSpecBuilder in project strimzi by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testNewToPendingProposalToProposalReadyRebalance.
/**
* Tests the transition from 'New' to 'PendingProposal' to 'ProposalReady'
*
* 1. A new KafkaRebalance resource is created; it is in the 'New' state
* 2. The operator requests a rebalance proposal via the Cruise Control REST API
* 3. The rebalance proposal is not ready on the first call; the operator starts polling the Cruise Control REST API
* 4. The KafkaRebalance resource moves to 'PendingProposal' state
* 5. The rebalance proposal is ready after the specified pending calls
* 6. The KafkaRebalance resource moves to 'ProposalReady' state
*/
@Test
public void testNewToPendingProposalToProposalReadyRebalance(VertxTestContext context) throws IOException, URISyntaxException {
// Setup the rebalance endpoint with the number of pending calls before a response is received.
MockCruiseControl.setupCCRebalanceResponse(ccServer, 2);
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, new KafkaRebalanceSpecBuilder().build());
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient);
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> {
// the resource moved from New to PendingProposal (due to the configured Mock server pending calls)
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.PendingProposal);
})).compose(v -> {
// trigger another reconcile to process the PendingProposal state
KafkaRebalance kr1 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr1);
}).onComplete(context.succeeding(v -> {
// the resource moved from PendingProposal to ProposalReady
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.ProposalReady);
checkpoint.flag();
}));
}
Aggregations