use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.
the class TopicOperatorMockTest method testCreatedWithDefaultsInKube.
@Test
public void testCreatedWithDefaultsInKube(VertxTestContext context) throws InterruptedException, ExecutionException {
int retention = 100_000_000;
KafkaTopic kt = new KafkaTopicBuilder().withNewMetadata().withName("my-topic").withNamespace(NAMESPACE).addToLabels(Labels.STRIMZI_KIND_LABEL, "topic").endMetadata().withNewSpec().addToConfig("retention.bytes", retention).endSpec().build();
testCreatedInKube(context, kt);
}
use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.
the class TopicOperatorMockTest method testCreatedWithoutTopicNameInKube.
@Test
public void testCreatedWithoutTopicNameInKube(VertxTestContext context) throws InterruptedException, ExecutionException {
LOGGER.info("Test started");
int retention = 100_000_000;
KafkaTopic kt = new KafkaTopicBuilder().withNewMetadata().withName("my-topic").withNamespace(NAMESPACE).addToLabels(Labels.STRIMZI_KIND_LABEL, "topic").addToLabels(Labels.KUBERNETES_NAME_LABEL, "topic-operator").endMetadata().withNewSpec().withPartitions(1).withReplicas(1).addToConfig("retention.bytes", retention).endSpec().build();
testCreatedInKube(context, kt);
}
use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.
the class TopicOperatorReplicationIT method testKafkaTopicModifiedChangedReplication.
@Test
public void testKafkaTopicModifiedChangedReplication() throws Exception {
// create the topicResource
String topicName = "test-kafkatopic-modified-with-changed-replication";
String resourceName = createTopic(topicName, asList(1));
// now change the topicResource
KafkaTopic changedTopic = new KafkaTopicBuilder(operation().inNamespace(NAMESPACE).withName(resourceName).get()).editOrNewSpec().withReplicas(2).endSpec().build();
operation().inNamespace(NAMESPACE).withName(resourceName).patch(changedTopic);
assertStatusNotReady(topicName, "Changing 'spec.replicas' is not supported. " + "This KafkaTopic's 'spec.replicas' should be reverted to 1 and then " + "the replication should be changed directly in Kafka.");
// Now do the revert
changedTopic = new KafkaTopicBuilder(operation().inNamespace(NAMESPACE).withName(resourceName).get()).editOrNewSpec().withReplicas(1).endSpec().build();
operation().inNamespace(NAMESPACE).withName(resourceName).patch(changedTopic);
assertStatusReady(topicName);
File file = File.createTempFile(getClass().getSimpleName(), ".json");
ObjectMapper mapper = new ObjectMapper();
ObjectNode root = new ObjectNode(mapper.getNodeFactory());
root.put("version", 1).putArray("partitions").addObject().put("topic", topicName).put("partition", 0).putArray("replicas").add(0).add(1);
mapper.writeValue(file, root);
LOGGER.info("Creating 2nd replica: {}", mapper.writeValueAsString(root));
// Now change it in Kafka
String reassignmentOutput = doReassignmentCommand("--bootstrap-server", kafkaCluster.getBootstrapServers(), "--reassignment-json-file", file.getAbsolutePath(), "--execute");
LOGGER.info(reassignmentOutput);
LOGGER.info("Waiting for reassignment completion");
waitFor(() -> {
String output = doReassignmentCommand("--bootstrap-server", kafkaCluster.getBootstrapServers(), "--reassignment-json-file", file.getAbsolutePath(), "--verify");
LOGGER.info(output);
if (output.contains("Reassignment of partition test-kafkatopic-modified-with-changed-replication-0 is still in progress")) {
return false;
} else {
assertThat("Reassignment is no longer in progress, but wasn't successful: " + output, output.contains("Reassignment of partition test-kafkatopic-modified-with-changed-replication-0 is complete"), is(true));
return true;
}
}, "reassignment completion");
// wait for reconciliation and that now replicas=2.
waitFor(() -> {
KafkaTopic kafkaTopic = Crds.topicOperation(kubeClient).inNamespace(NAMESPACE).withName(resourceName).get();
LOGGER.info(kafkaTopic == null ? "Null topic" : kafkaTopic.toString());
return kafkaTopic.getSpec().getReplicas() == 2;
}, "KafkaTopic.spec.replicas=2");
// And check that the status is ready
assertStatusReady(topicName);
}
use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.
the class TopicOperatorTest method testOnKafkaTopicChanged.
@Test
public void testOnKafkaTopicChanged(VertxTestContext context) {
Topic kubeTopic = new Topic.Builder(topicName, resourceName, 10, (short) 2, map("cleanup.policy", "baz"), null).build();
Topic kafkaTopic = new Topic.Builder(topicName, resourceName, 10, (short) 2, map("cleanup.policy", "bar"), null).build();
Topic privateTopic = kafkaTopic;
KafkaTopic resource = TopicSerialization.toTopicResource(kubeTopic, labels);
LogContext logContext = LogContext.zkWatch("///", topicName.toString(), topicOperator.getNamespace(), topicName.toString());
mockKafka.setCreateTopicResponse(topicName.toString(), null).createTopic(Reconciliation.DUMMY_RECONCILIATION, kafkaTopic);
mockKafka.setTopicMetadataResponse(topicName, Utils.getTopicMetadata(kafkaTopic), null);
mockKafka.setUpdateTopicResponse(topicName -> Future.succeededFuture());
mockTopicStore.setCreateTopicResponse(topicName, null).create(privateTopic);
mockTopicStore.setUpdateTopicResponse(topicName, null);
mockK8s.setCreateResponse(resourceName, null);
mockK8s.createResource(resource).onComplete(ar -> {
assertSucceeded(context, ar);
});
mockK8s.setModifyResponse(resourceName, null);
CountDownLatch async = new CountDownLatch(3);
topicOperator.onResourceEvent(logContext, resource, MODIFIED).onComplete(ar -> {
assertSucceeded(context, ar);
context.verify(() -> assertThat(mockKafka.getTopicState(topicName).getConfig().get("cleanup.policy"), is("baz")));
mockTopicStore.read(topicName).onComplete(ar2 -> {
assertSucceeded(context, ar2);
context.verify(() -> assertThat(ar2.result().getConfig().get("cleanup.policy"), is("baz")));
async.countDown();
});
mockK8s.getFromName(resourceName).onComplete(ar2 -> {
assertSucceeded(context, ar2);
context.verify(() -> assertThat(ar2.result(), is(notNullValue())));
context.verify(() -> assertThat(TopicSerialization.fromTopicResource(ar2.result()).getConfig().get("cleanup.policy"), is("baz")));
async.countDown();
});
context.verify(() -> {
MeterRegistry registry = metrics.meterRegistry();
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "resource.state").tag("kind", "KafkaTopic").tag("name", topicName.toString()).tag("resource-namespace", "default-namespace").gauge().value(), is(1.0));
});
async.countDown();
try {
async.await(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
context.completeNow();
});
}
use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.
the class TopicOperatorTest method testOnKafkaTopicAdded_invalidResource.
/**
* Test what happens when a non-topic KafkaTopic gets created in kubernetes
*/
@Test
public void testOnKafkaTopicAdded_invalidResource(VertxTestContext context) {
KafkaTopic kafkaTopic = new KafkaTopicBuilder().withMetadata(new ObjectMetaBuilder().withName("invalid").withLabels(labels.labels()).build()).withNewSpec().withReplicas(1).withPartitions(1).withConfig(singletonMap(null, null)).endSpec().build();
String errorMessage = "KafkaTopic's spec.config has invalid entry: The key 'null' of the topic config is invalid: The value corresponding to the key must have a string, number or boolean value but the value was null";
mockK8s.setGetFromNameResponse(new ResourceName(kafkaTopic), Future.succeededFuture(kafkaTopic));
LogContext logContext = LogContext.kubeWatch(Watcher.Action.ADDED, kafkaTopic);
Checkpoint async = context.checkpoint();
topicOperator.onResourceEvent(logContext, kafkaTopic, ADDED).onComplete(ar -> {
assertFailed(context, ar);
context.verify(() -> assertThat(ar.cause(), instanceOf(InvalidTopicException.class)));
context.verify(() -> assertThat(ar.cause().getMessage(), is(errorMessage)));
mockKafka.assertEmpty(context);
mockTopicStore.assertEmpty(context);
assertNotReadyStatus(context, new InvalidTopicException(null, ar.cause().getMessage()));
context.verify(() -> {
MeterRegistry registry = metrics.meterRegistry();
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations").tag("kind", "KafkaTopic").counter().count(), is(0.0));
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.successful").tag("kind", "KafkaTopic").counter().count(), is(0.0));
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.failed").tag("kind", "KafkaTopic").counter().count(), is(0.0));
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.duration").tag("kind", "KafkaTopic").timer().count(), is(0L));
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "reconciliations.duration").tag("kind", "KafkaTopic").timer().totalTime(TimeUnit.MILLISECONDS), is(0.0));
assertThat(registry.get(TopicOperator.METRICS_PREFIX + "resource.state").tag("kind", "KafkaTopic").tag("name", "invalid").tag("resource-namespace", "default-namespace").tag("reason", errorMessage).gauge().value(), is(0.0));
});
async.flag();
});
}
Aggregations