use of io.strimzi.controller.cluster.Reconciliation in project strimzi by strimzi.
the class KafkaConnectS2IAssemblyOperatorTest method testDeleteCluster.
@Test
public void testDeleteCluster(TestContext context) {
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
DeploymentConfigOperator mockDcOps = mock(DeploymentConfigOperator.class);
BuildConfigOperator mockBcOps = mock(BuildConfigOperator.class);
ImageStreamOperator mockIsOps = mock(ImageStreamOperator.class);
String clusterCmName = "foo";
String clusterCmNamespace = "test";
KafkaConnectS2ICluster connect = KafkaConnectS2ICluster.fromConfigMap(ResourceUtils.createEmptyKafkaConnectS2IClusterConfigMap(clusterCmNamespace, clusterCmName));
when(mockDcOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateDeploymentConfig());
when(mockIsOps.get(clusterCmNamespace, connect.getSourceImageStreamName())).thenReturn(connect.generateSourceImageStream());
ArgumentCaptor<String> serviceNamespaceCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> serviceNameCaptor = ArgumentCaptor.forClass(String.class);
when(mockServiceOps.reconcile(serviceNamespaceCaptor.capture(), serviceNameCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> dcNamespaceCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> dcNameCaptor = ArgumentCaptor.forClass(String.class);
when(mockDcOps.reconcile(dcNamespaceCaptor.capture(), dcNameCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> isNamespaceCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> isNameCaptor = ArgumentCaptor.forClass(String.class);
when(mockIsOps.reconcile(isNamespaceCaptor.capture(), isNameCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
ArgumentCaptor<String> bcNamespaceCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> bcNameCaptor = ArgumentCaptor.forClass(String.class);
when(mockBcOps.reconcile(bcNamespaceCaptor.capture(), bcNameCaptor.capture(), isNull())).thenReturn(Future.succeededFuture());
KafkaConnectS2IAssemblyOperator ops = new KafkaConnectS2IAssemblyOperator(vertx, true, mockCmOps, mockDcOps, mockServiceOps, mockIsOps, mockBcOps);
Async async = context.async();
ops.delete(new Reconciliation("test-trigger", AssemblyType.CONNECT_S2I, clusterCmNamespace, clusterCmName), createResult -> {
context.assertTrue(createResult.succeeded());
// Verify service
context.assertEquals(1, serviceNameCaptor.getAllValues().size());
context.assertEquals(clusterCmNamespace, serviceNamespaceCaptor.getValue());
context.assertEquals(connect.getName(), serviceNameCaptor.getValue());
// Vertify deployment Config
context.assertEquals(1, dcNameCaptor.getAllValues().size());
context.assertEquals(clusterCmNamespace, dcNamespaceCaptor.getValue());
context.assertEquals(connect.getName(), dcNameCaptor.getValue());
// Vertify BuildConfig
context.assertEquals(1, bcNameCaptor.getAllValues().size());
context.assertEquals(clusterCmNamespace, bcNamespaceCaptor.getValue());
context.assertEquals(connect.getName(), bcNameCaptor.getValue());
// Vertify ImageStreams
int sisIndex = (connect.getSourceImageStreamName()).equals(isNameCaptor.getAllValues().get(0)) ? 0 : 1;
int tisIndex = (connect.getName()).equals(isNameCaptor.getAllValues().get(0)) ? 0 : 1;
context.assertEquals(2, isNameCaptor.getAllValues().size());
context.assertEquals(clusterCmNamespace, isNamespaceCaptor.getAllValues().get(sisIndex));
context.assertEquals(connect.getSourceImageStreamName(), isNameCaptor.getAllValues().get(sisIndex));
context.assertEquals(clusterCmNamespace, isNamespaceCaptor.getAllValues().get(tisIndex));
context.assertEquals(connect.getName(), isNameCaptor.getAllValues().get(tisIndex));
async.complete();
});
}
use of io.strimzi.controller.cluster.Reconciliation in project strimzi by strimzi.
the class KafkaConnectS2IAssemblyOperatorTest method testUpdateClusterScaleUp.
@Test
public void testUpdateClusterScaleUp(TestContext context) {
int scaleTo = 4;
String newReplicas = String.valueOf(scaleTo);
ConfigMapOperator mockCmOps = mock(ConfigMapOperator.class);
ServiceOperator mockServiceOps = mock(ServiceOperator.class);
DeploymentConfigOperator mockDcOps = mock(DeploymentConfigOperator.class);
BuildConfigOperator mockBcOps = mock(BuildConfigOperator.class);
ImageStreamOperator mockIsOps = mock(ImageStreamOperator.class);
String clusterCmName = "foo";
String clusterCmNamespace = "test";
ConfigMap clusterCm = ResourceUtils.createEmptyKafkaConnectS2IClusterConfigMap(clusterCmNamespace, clusterCmName);
KafkaConnectS2ICluster connect = KafkaConnectS2ICluster.fromConfigMap(clusterCm);
// Change replicas to create ScaleUp
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.generateDeploymentConfig());
when(mockIsOps.get(clusterCmNamespace, connect.getSourceImageStreamName())).thenReturn(connect.generateSourceImageStream());
when(mockIsOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateTargetImageStream());
when(mockBcOps.get(clusterCmNamespace, connect.getName())).thenReturn(connect.generateBuildConfig());
when(mockServiceOps.reconcile(any(), any(), any())).thenReturn(Future.succeededFuture());
when(mockDcOps.reconcile(any(), 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);
when(mockIsOps.reconcile(any(), any(), any())).thenReturn(Future.succeededFuture());
when(mockBcOps.reconcile(any(), any(), any())).thenReturn(Future.succeededFuture());
KafkaConnectS2IAssemblyOperator ops = new KafkaConnectS2IAssemblyOperator(vertx, true, mockCmOps, mockDcOps, mockServiceOps, mockIsOps, mockBcOps);
Async async = context.async();
ops.createOrUpdate(new Reconciliation("test-trigger", AssemblyType.CONNECT_S2I, clusterCmNamespace, clusterCmName), clusterCm, createResult -> {
context.assertTrue(createResult.succeeded());
verify(mockDcOps).scaleUp(clusterCmNamespace, connect.getName(), scaleTo);
async.complete();
});
}
use of io.strimzi.controller.cluster.Reconciliation in project strimzi by strimzi.
the class AbstractAssemblyOperator method reconcileAll.
/**
* Reconcile assembly resources in the given namespace having the given selector.
* Reconciliation works by getting the assembly ConfigMaps in the given namespace with the given selector and
* comparing with the corresponding {@linkplain #getResources(String) resource}.
* <ul>
* <li>An assembly will be {@linkplain #createOrUpdate(Reconciliation, ConfigMap, Handler) created} for all ConfigMaps without same-named resources</li>
* <li>An assembly will be {@linkplain #delete(Reconciliation, Handler) deleted} for all resources without same-named ConfigMaps</li>
* </ul>
*
* @param trigger A description of the triggering event (timer or watch), used for logging
* @param namespace The namespace
* @param selector The selector
*/
public final CountDownLatch reconcileAll(String trigger, String namespace, Labels selector) {
Labels selectorWithCluster = selector.withType(assemblyType);
// get ConfigMaps with kind=cluster&type=kafka (or connect, or connect-s2i) for the corresponding cluster type
List<ConfigMap> cms = configMapOperations.list(namespace, selectorWithCluster);
Set<String> cmsNames = cms.stream().map(cm -> cm.getMetadata().getName()).collect(Collectors.toSet());
log.debug("reconcileAll({}, {}): ConfigMaps with labels {}: {}", assemblyType, trigger, selectorWithCluster, cmsNames);
// get resources with kind=cluster&type=kafka (or connect, or connect-s2i)
List<? extends HasMetadata> resources = getResources(namespace);
// now extract the cluster name from those
Set<String> resourceNames = resources.stream().filter(// exclude Cluster CM, which won't have a cluster label
r -> Labels.kind(r) == null).map(Labels::cluster).collect(Collectors.toSet());
log.debug("reconcileAll({}, {}): Other resources with labels {}: {}", assemblyType, trigger, selectorWithCluster, resourceNames);
cmsNames.addAll(resourceNames);
// We use a latch so that callers (specifically, test callers) know when the reconciliation is complete
// Using futures would be more complex for no benefit
CountDownLatch latch = new CountDownLatch(cmsNames.size());
for (String name : cmsNames) {
Reconciliation reconciliation = new Reconciliation(trigger, assemblyType, namespace, name);
reconcileAssembly(reconciliation, result -> {
if (result.succeeded()) {
log.info("{}: Assembly reconciled", reconciliation);
} else {
log.error("{}: Failed to reconcile", reconciliation);
}
latch.countDown();
});
}
return latch;
}
use of io.strimzi.controller.cluster.Reconciliation in project strimzi by strimzi.
the class KafkaConnectAssemblyOperator method createOrUpdate.
@Override
protected void createOrUpdate(Reconciliation reconciliation, ConfigMap assemblyCm, Handler<AsyncResult<Void>> handler) {
String namespace = reconciliation.namespace();
String name = reconciliation.assemblyName();
KafkaConnectCluster connect = KafkaConnectCluster.fromConfigMap(assemblyCm);
log.info("{}: Updating Kafka Connect cluster", reconciliation, name, namespace);
Future<Void> chainFuture = Future.future();
deploymentOperations.scaleDown(namespace, connect.getName(), connect.getReplicas()).compose(scale -> serviceOperations.reconcile(namespace, connect.getName(), connect.generateService())).compose(i -> deploymentOperations.reconcile(namespace, connect.getName(), connect.generateDeployment())).compose(i -> deploymentOperations.scaleUp(namespace, connect.getName(), connect.getReplicas()).map((Void) null)).compose(chainFuture::complete, chainFuture);
chainFuture.setHandler(handler);
}
use of io.strimzi.controller.cluster.Reconciliation in project strimzi by strimzi.
the class KafkaAssemblyOperator method createOrUpdateZk.
private final Future<Void> createOrUpdateZk(Reconciliation reconciliation, ConfigMap assemblyCm) {
String namespace = assemblyCm.getMetadata().getNamespace();
String name = assemblyCm.getMetadata().getName();
log.info("{}: create/update zookeeper {}", reconciliation, name);
ZookeeperCluster zk = ZookeeperCluster.fromConfigMap(assemblyCm);
Service service = zk.generateService();
Service headlessService = zk.generateHeadlessService();
Future<Void> chainFuture = Future.future();
zkSetOperations.scaleDown(namespace, zk.getName(), zk.getReplicas()).compose(scale -> serviceOperations.reconcile(namespace, zk.getName(), service)).compose(i -> serviceOperations.reconcile(namespace, zk.getHeadlessName(), headlessService)).compose(i -> configMapOperations.reconcile(namespace, zk.getMetricsConfigName(), zk.generateMetricsConfigMap())).compose(i -> zkSetOperations.reconcile(namespace, zk.getName(), zk.generateStatefulSet(isOpenShift))).compose(diffs -> {
if (diffs instanceof ReconcileResult.Patched && ((ReconcileResult.Patched<Boolean>) diffs).differences()) {
return zkSetOperations.rollingUpdate(namespace, zk.getName());
} else {
return Future.succeededFuture();
}
}).compose(i -> zkSetOperations.scaleUp(namespace, zk.getName(), zk.getReplicas())).compose(scale -> serviceOperations.endpointReadiness(namespace, service, 1_000, operationTimeoutMs)).compose(i -> serviceOperations.endpointReadiness(namespace, headlessService, 1_000, operationTimeoutMs)).compose(chainFuture::complete, chainFuture);
return chainFuture;
}
Aggregations