use of io.strimzi.controller.cluster.operator.resource.DeploymentOperator in project strimzi by strimzi.
the class KafkaAssemblyOperatorTest method updateCluster.
private void updateCluster(TestContext context, ConfigMap originalCm, ConfigMap clusterCm, boolean kafkaRolling, boolean zkRolling) {
KafkaCluster originalKafkaCluster = KafkaCluster.fromConfigMap(originalCm);
KafkaCluster updatedKafkaCluster = KafkaCluster.fromConfigMap(clusterCm);
ZookeeperCluster originalZookeeperCluster = ZookeeperCluster.fromConfigMap(originalCm);
ZookeeperCluster updatedZookeeperCluster = ZookeeperCluster.fromConfigMap(clusterCm);
TopicController originalTopicController = TopicController.fromConfigMap(originalCm);
// create CM, Service, headless service, statefulset and so on
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
ZookeeperSetOperator mockZsOps = mock(ZookeeperSetOperator.class);
KafkaSetOperator mockKsOps = mock(KafkaSetOperator.class);
PvcOperator mockPvcOps = mock(PvcOperator.class);
DeploymentOperator mockDepOps = mock(DeploymentOperator.class);
String clusterCmName = clusterCm.getMetadata().getName();
String clusterCmNamespace = clusterCm.getMetadata().getNamespace();
// Mock CM get
when(mockCmOps.get(clusterCmNamespace, clusterCmName)).thenReturn(clusterCm);
ConfigMap metricsCm = new ConfigMapBuilder().withNewMetadata().withName(KafkaCluster.metricConfigsName(clusterCmName)).withNamespace(clusterCmNamespace).endMetadata().withData(Collections.singletonMap(AbstractModel.METRICS_CONFIG_FILE, METRICS_CONFIG)).build();
when(mockCmOps.get(clusterCmNamespace, KafkaCluster.metricConfigsName(clusterCmName))).thenReturn(metricsCm);
ConfigMap zkMetricsCm = new ConfigMapBuilder().withNewMetadata().withName(ZookeeperCluster.zookeeperMetricsName(clusterCmName)).withNamespace(clusterCmNamespace).endMetadata().withData(Collections.singletonMap(AbstractModel.METRICS_CONFIG_FILE, METRICS_CONFIG)).build();
when(mockCmOps.get(clusterCmNamespace, ZookeeperCluster.zookeeperMetricsName(clusterCmName))).thenReturn(zkMetricsCm);
// Mock Service gets
when(mockServiceOps.get(clusterCmNamespace, KafkaCluster.kafkaClusterName(clusterCmName))).thenReturn(originalKafkaCluster.generateService());
when(mockServiceOps.get(clusterCmNamespace, KafkaCluster.headlessName(clusterCmName))).thenReturn(originalKafkaCluster.generateHeadlessService());
when(mockServiceOps.get(clusterCmNamespace, ZookeeperCluster.zookeeperClusterName(clusterCmName))).thenReturn(originalKafkaCluster.generateService());
when(mockServiceOps.get(clusterCmNamespace, ZookeeperCluster.zookeeperHeadlessName(clusterCmName))).thenReturn(originalZookeeperCluster.generateHeadlessService());
when(mockServiceOps.endpointReadiness(eq(clusterCmNamespace), any(), anyLong(), anyLong())).thenReturn(Future.succeededFuture());
// Mock StatefulSet get
when(mockKsOps.get(clusterCmNamespace, KafkaCluster.kafkaClusterName(clusterCmName))).thenReturn(originalKafkaCluster.generateStatefulSet(openShift));
when(mockZsOps.get(clusterCmNamespace, ZookeeperCluster.zookeeperClusterName(clusterCmName))).thenReturn(originalZookeeperCluster.generateStatefulSet(openShift));
// Mock Deployment get
if (originalTopicController != null) {
when(mockDepOps.get(clusterCmNamespace, TopicController.topicControllerName(clusterCmName))).thenReturn(originalTopicController.generateDeployment());
}
// Mock CM patch
Set<String> metricsCms = set();
doAnswer(invocation -> {
metricsCms.add(invocation.getArgument(1));
return Future.succeededFuture();
}).when(mockCmOps).reconcile(eq(clusterCmNamespace), anyString(), any());
// Mock Service patch (both service and headless service
ArgumentCaptor<String> patchedServicesCaptor = ArgumentCaptor.forClass(String.class);
when(mockServiceOps.reconcile(eq(clusterCmNamespace), patchedServicesCaptor.capture(), any())).thenReturn(Future.succeededFuture());
// Mock StatefulSet patch
when(mockZsOps.reconcile(anyString(), anyString(), any())).thenReturn(Future.succeededFuture(ReconcileResult.patched(zkRolling)));
when(mockKsOps.reconcile(anyString(), anyString(), any())).thenReturn(Future.succeededFuture(ReconcileResult.patched(kafkaRolling)));
// Mock StatefulSet rollingUpdate
Set<String> rollingRestarts = set();
// Mock StatefulSet scaleUp
ArgumentCaptor<String> scaledUpCaptor = ArgumentCaptor.forClass(String.class);
when(mockZsOps.scaleUp(anyString(), scaledUpCaptor.capture(), anyInt())).thenReturn(Future.succeededFuture(42));
// Mock StatefulSet scaleDown
ArgumentCaptor<String> scaledDownCaptor = ArgumentCaptor.forClass(String.class);
when(mockZsOps.scaleDown(anyString(), scaledDownCaptor.capture(), anyInt())).thenReturn(Future.succeededFuture(42));
when(mockZsOps.rollingUpdate(anyString(), anyString())).thenAnswer(i -> {
if (!zkRolling) {
context.fail("Unexpected rolling update");
}
return Future.succeededFuture();
});
// ArgumentCaptor<String> scaledUpCaptor = ArgumentCaptor.forClass(String.class);
when(mockKsOps.scaleUp(anyString(), scaledUpCaptor.capture(), anyInt())).thenReturn(Future.succeededFuture(42));
// Mock StatefulSet scaleDown
// ArgumentCaptor<String> scaledDownCaptor = ArgumentCaptor.forClass(String.class);
when(mockKsOps.scaleDown(anyString(), scaledDownCaptor.capture(), anyInt())).thenReturn(Future.succeededFuture(42));
when(mockKsOps.rollingUpdate(anyString(), anyString())).thenAnswer(i -> {
if (!kafkaRolling) {
context.fail("Unexpected rolling update");
}
return Future.succeededFuture();
});
// Mock Deployment patch
ArgumentCaptor<String> depCaptor = ArgumentCaptor.forClass(String.class);
when(mockDepOps.reconcile(anyString(), depCaptor.capture(), any())).thenReturn(Future.succeededFuture());
KafkaAssemblyOperator ops = new KafkaAssemblyOperator(vertx, openShift, ClusterControllerConfig.DEFAULT_OPERATION_TIMEOUT_MS, mockCmOps, mockServiceOps, mockZsOps, mockKsOps, mockPvcOps, mockDepOps);
// Now try to update a KafkaCluster based on this CM
Async async = context.async();
ops.createOrUpdate(new Reconciliation("test-trigger", AssemblyType.KAFKA, clusterCmNamespace, clusterCmName), clusterCm, createResult -> {
if (createResult.failed())
createResult.cause().printStackTrace();
context.assertTrue(createResult.succeeded());
// rolling restart
Set<String> expectedRollingRestarts = set();
if (KafkaSetOperator.needsRollingUpdate(new StatefulSetDiff(originalKafkaCluster.generateStatefulSet(openShift), updatedKafkaCluster.generateStatefulSet(openShift)))) {
expectedRollingRestarts.add(originalKafkaCluster.getName());
}
if (ZookeeperSetOperator.needsRollingUpdate(new StatefulSetDiff(originalZookeeperCluster.generateStatefulSet(openShift), updatedZookeeperCluster.generateStatefulSet(openShift)))) {
expectedRollingRestarts.add(originalZookeeperCluster.getName());
}
// No metrics config => no CMs created
verify(mockCmOps, never()).createOrUpdate(any());
verifyNoMoreInteractions(mockPvcOps);
async.complete();
});
}
use of io.strimzi.controller.cluster.operator.resource.DeploymentOperator in project strimzi by strimzi.
the class KafkaAssemblyOperatorTest method deleteCluster.
private void deleteCluster(TestContext context, ConfigMap clusterCm) {
ZookeeperCluster zookeeperCluster = ZookeeperCluster.fromConfigMap(clusterCm);
KafkaCluster kafkaCluster = KafkaCluster.fromConfigMap(clusterCm);
TopicController topicController = TopicController.fromConfigMap(clusterCm);
// create CM, Service, headless service, statefulset
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
ZookeeperSetOperator mockZsOps = mock(ZookeeperSetOperator.class);
KafkaSetOperator mockKsOps = mock(KafkaSetOperator.class);
PvcOperator mockPvcOps = mock(PvcOperator.class);
DeploymentOperator mockDepOps = mock(DeploymentOperator.class);
String clusterCmName = clusterCm.getMetadata().getName();
String clusterCmNamespace = clusterCm.getMetadata().getNamespace();
StatefulSet kafkaSs = kafkaCluster.generateStatefulSet(true);
StatefulSet zkSs = zookeeperCluster.generateStatefulSet(true);
when(mockKsOps.get(clusterCmNamespace, KafkaCluster.kafkaClusterName(clusterCmName))).thenReturn(kafkaSs);
when(mockZsOps.get(clusterCmNamespace, ZookeeperCluster.zookeeperClusterName(clusterCmName))).thenReturn(zkSs);
when(mockCmOps.get(clusterCmNamespace, clusterCmName)).thenReturn(clusterCm);
ArgumentCaptor<String> serviceCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> ssCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> metricsCaptor = ArgumentCaptor.forClass(String.class);
when(mockCmOps.reconcile(eq(clusterCmNamespace), metricsCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
when(mockServiceOps.reconcile(eq(clusterCmNamespace), serviceCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
when(mockKsOps.reconcile(anyString(), ssCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
when(mockZsOps.reconcile(anyString(), ssCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> pvcCaptor = ArgumentCaptor.forClass(String.class);
when(mockPvcOps.reconcile(eq(clusterCmNamespace), pvcCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> depCaptor = ArgumentCaptor.forClass(String.class);
when(mockDepOps.reconcile(eq(clusterCmNamespace), depCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
if (topicController != null) {
Deployment tcDep = topicController.generateDeployment();
when(mockDepOps.get(clusterCmNamespace, TopicController.topicControllerName(clusterCmName))).thenReturn(tcDep);
}
KafkaAssemblyOperator ops = new KafkaAssemblyOperator(vertx, openShift, ClusterControllerConfig.DEFAULT_OPERATION_TIMEOUT_MS, mockCmOps, mockServiceOps, mockZsOps, mockKsOps, mockPvcOps, mockDepOps);
// Now try to delete a KafkaCluster based on this CM
Async async = context.async();
ops.delete(new Reconciliation("test-trigger", AssemblyType.KAFKA, clusterCmNamespace, clusterCmName), createResult -> {
context.assertTrue(createResult.succeeded());
/*Set<String> metricsNames = new HashSet<>();
if (kafkaCluster.isMetricsEnabled()) {
metricsNames.add(KafkaCluster.metricConfigsName(clusterCmName));
}
if (zookeeperCluster.isMetricsEnabled()) {
metricsNames.add(ZookeeperCluster.zookeeperMetricsName(clusterCmName));
}
context.assertEquals(metricsNames, captured(metricsCaptor));*/
verify(mockZsOps).reconcile(eq(clusterCmNamespace), eq(ZookeeperCluster.zookeeperClusterName(clusterCmName)), isNull());
context.assertEquals(set(ZookeeperCluster.zookeeperHeadlessName(clusterCmName), ZookeeperCluster.zookeeperClusterName(clusterCmName), KafkaCluster.kafkaClusterName(clusterCmName), KafkaCluster.headlessName(clusterCmName)), captured(serviceCaptor));
// verify deleted Statefulsets
context.assertEquals(set(zookeeperCluster.getName(), kafkaCluster.getName()), captured(ssCaptor));
// PvcOperations only used for deletion
Set<String> expectedPvcDeletions = new HashSet<>();
for (int i = 0; deleteClaim && i < kafkaCluster.getReplicas(); i++) {
expectedPvcDeletions.add("data-" + clusterCmName + "-kafka-" + i);
}
for (int i = 0; deleteClaim && i < zookeeperCluster.getReplicas(); i++) {
expectedPvcDeletions.add("data-" + clusterCmName + "-zookeeper-" + i);
}
context.assertEquals(expectedPvcDeletions, captured(pvcCaptor));
// if topic controller configuration was defined in the CM
if (topicController != null) {
Set<String> expectedDepNames = new HashSet<>();
expectedDepNames.add(TopicController.topicControllerName(clusterCmName));
context.assertEquals(expectedDepNames, captured(depCaptor));
}
async.complete();
});
}
use of io.strimzi.controller.cluster.operator.resource.DeploymentOperator in project strimzi by strimzi.
the class KafkaConnectAssemblyOperatorTest method testUpdateCluster.
@Test
public void testUpdateCluster(TestContext context) {
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
DeploymentOperator mockDcOps = mock(DeploymentOperator.class);
String clusterCmName = "foo";
String clusterCmNamespace = "test";
ConfigMap clusterCm = ResourceUtils.createEmptyKafkaConnectClusterConfigMap(clusterCmNamespace, clusterCmName);
KafkaConnectCluster connect = KafkaConnectCluster.fromConfigMap(clusterCm);
// Change the image to generate some diff
clusterCm.getData().put("image", "some/different:image");
when(mockCmOps.get(clusterCmNamespace, clusterCmName)).thenReturn(clusterCm);
when(mockServiceOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateService());
when(mockDcOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateDeployment());
ArgumentCaptor<String> serviceNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Service> serviceCaptor = ArgumentCaptor.forClass(Service.class);
when(mockServiceOps.reconcile(eq(clusterCmNamespace), serviceNameCaptor.capture(), serviceCaptor.capture())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> dcNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Deployment> dcCaptor = ArgumentCaptor.forClass(Deployment.class);
when(mockDcOps.reconcile(eq(clusterCmNamespace), dcNameCaptor.capture(), dcCaptor.capture())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> dcScaleUpNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Integer> dcScaleUpReplicasCaptor = ArgumentCaptor.forClass(Integer.class);
when(mockDcOps.scaleUp(eq(clusterCmNamespace), dcScaleUpNameCaptor.capture(), dcScaleUpReplicasCaptor.capture())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> dcScaleDownNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Integer> dcScaleDownReplicasCaptor = ArgumentCaptor.forClass(Integer.class);
when(mockDcOps.scaleDown(eq(clusterCmNamespace), dcScaleDownNameCaptor.capture(), dcScaleDownReplicasCaptor.capture())).thenReturn(Future.succeededFuture());
KafkaConnectAssemblyOperator ops = new KafkaConnectAssemblyOperator(vertx, true, mockCmOps, mockDcOps, mockServiceOps);
Async async = context.async();
ops.createOrUpdate(new Reconciliation("test-trigger", AssemblyType.CONNECT, clusterCmNamespace, clusterCmName), clusterCm, createResult -> {
context.assertTrue(createResult.succeeded());
KafkaConnectCluster compareTo = KafkaConnectCluster.fromConfigMap(clusterCm);
// Vertify service
List<Service> capturedServices = serviceCaptor.getAllValues();
context.assertEquals(1, capturedServices.size());
Service service = capturedServices.get(0);
context.assertEquals(compareTo.getName(), service.getMetadata().getName());
context.assertEquals(compareTo.generateService(), service, "Services are not equal");
// Verify Deployment
List<Deployment> capturedDc = dcCaptor.getAllValues();
context.assertEquals(1, capturedDc.size());
Deployment dc = capturedDc.get(0);
context.assertEquals(compareTo.getName(), dc.getMetadata().getName());
context.assertEquals(compareTo.generateDeployment(), dc, "Deployments are not equal");
// Verify scaleDown / scaleUp were not called
context.assertEquals(1, dcScaleDownNameCaptor.getAllValues().size());
context.assertEquals(1, dcScaleUpNameCaptor.getAllValues().size());
async.complete();
});
}
use of io.strimzi.controller.cluster.operator.resource.DeploymentOperator in project strimzi by strimzi.
the class KafkaConnectAssemblyOperatorTest method testReconcile.
@Test
public void testReconcile(TestContext context) {
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
DeploymentOperator mockDcOps = mock(DeploymentOperator.class);
String clusterCmNamespace = "test";
ConfigMap foo = ResourceUtils.createEmptyKafkaConnectClusterConfigMap(clusterCmNamespace, "foo");
ConfigMap bar = ResourceUtils.createEmptyKafkaConnectClusterConfigMap(clusterCmNamespace, "bar");
ConfigMap baz = ResourceUtils.createEmptyKafkaConnectClusterConfigMap(clusterCmNamespace, "baz");
when(mockCmOps.list(eq(clusterCmNamespace), any())).thenReturn(asList(foo, bar));
// when requested ConfigMap for a specific Kafka Connect cluster
when(mockCmOps.get(eq(clusterCmNamespace), eq("foo"))).thenReturn(foo);
when(mockCmOps.get(eq(clusterCmNamespace), eq("bar"))).thenReturn(bar);
// providing the list of ALL Deployments for all the Kafka Connect clusters
Labels newLabels = Labels.forType(AssemblyType.CONNECT);
when(mockDcOps.list(eq(clusterCmNamespace), eq(newLabels))).thenReturn(asList(KafkaConnectCluster.fromConfigMap(bar).generateDeployment(), KafkaConnectCluster.fromConfigMap(baz).generateDeployment()));
// providing the list Deployments for already "existing" Kafka Connect clusters
Labels barLabels = Labels.forCluster("bar");
when(mockDcOps.list(eq(clusterCmNamespace), eq(barLabels))).thenReturn(asList(KafkaConnectCluster.fromConfigMap(bar).generateDeployment()));
Labels bazLabels = Labels.forCluster("baz");
when(mockDcOps.list(eq(clusterCmNamespace), eq(bazLabels))).thenReturn(asList(KafkaConnectCluster.fromConfigMap(baz).generateDeployment()));
Set<String> createdOrUpdated = new HashSet<>();
Set<String> deleted = new HashSet<>();
Async async = context.async(3);
KafkaConnectAssemblyOperator ops = new KafkaConnectAssemblyOperator(vertx, true, mockCmOps, mockDcOps, mockServiceOps) {
@Override
public void createOrUpdate(Reconciliation reconciliation, ConfigMap assemblyCm, Handler h) {
createdOrUpdated.add(assemblyCm.getMetadata().getName());
async.countDown();
h.handle(Future.succeededFuture());
}
@Override
public void delete(Reconciliation reconciliation, Handler h) {
deleted.add(reconciliation.assemblyName());
async.countDown();
h.handle(Future.succeededFuture());
}
};
// Now try to reconcile all the Kafka Connect clusters
ops.reconcileAll("test", clusterCmNamespace, Labels.EMPTY);
async.await();
context.assertEquals(new HashSet(asList("foo", "bar")), createdOrUpdated);
context.assertEquals(singleton("baz"), deleted);
}
use of io.strimzi.controller.cluster.operator.resource.DeploymentOperator in project strimzi by strimzi.
the class KafkaConnectAssemblyOperatorTest method testUpdateClusterScaleDown.
@Test
public void testUpdateClusterScaleDown(TestContext context) {
int scaleTo = 2;
String newReplicas = String.valueOf(scaleTo);
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
DeploymentOperator mockDcOps = mock(DeploymentOperator.class);
String clusterCmName = "foo";
String clusterCmNamespace = "test";
ConfigMap clusterCm = ResourceUtils.createEmptyKafkaConnectClusterConfigMap(clusterCmNamespace, clusterCmName);
KafkaConnectCluster connect = KafkaConnectCluster.fromConfigMap(clusterCm);
// Change replicas to create ScaleDown
clusterCm.getData().put(KafkaConnectCluster.KEY_REPLICAS, newReplicas);
when(mockCmOps.get(clusterCmNamespace, clusterCmName)).thenReturn(clusterCm);
when(mockServiceOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateService());
when(mockDcOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateDeployment());
when(mockServiceOps.reconcile(eq(clusterCmNamespace), any(), any())).thenReturn(Future.succeededFuture());
when(mockDcOps.reconcile(eq(clusterCmNamespace), any(), any())).thenReturn(Future.succeededFuture());
doAnswer(i -> Future.succeededFuture(scaleTo)).when(mockDcOps).scaleUp(clusterCmNamespace, connect.getName(), scaleTo);
doAnswer(i -> Future.succeededFuture(scaleTo)).when(mockDcOps).scaleDown(clusterCmNamespace, connect.getName(), scaleTo);
KafkaConnectAssemblyOperator ops = new KafkaConnectAssemblyOperator(vertx, true, mockCmOps, mockDcOps, mockServiceOps);
Async async = context.async();
ops.createOrUpdate(new Reconciliation("test-trigger", AssemblyType.CONNECT, clusterCmNamespace, clusterCmName), clusterCm, createResult -> {
context.assertTrue(createResult.succeeded());
verify(mockDcOps).scaleUp(clusterCmNamespace, connect.getName(), scaleTo);
async.complete();
});
}
Aggregations