use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.
the class ConnectBuildOperator method kubernetesBuildWaitForFinish.
/**
* Waits for the Kafka Connect build to finish and collects the results from it
*
* @param reconciliation The reconciliation
* @param namespace Namespace of the Connect cluster
* @param connectBuild KafkaConnectBuild object
*
* @return Future which completes with the built image when the build is finished (or fails if it fails)
*/
private Future<String> kubernetesBuildWaitForFinish(Reconciliation reconciliation, String namespace, KafkaConnectBuild connectBuild) {
return podOperator.waitFor(reconciliation, namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()), "complete", 1_000, connectBuildTimeoutMs, (ignore1, ignore2) -> kubernetesBuildPodFinished(namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()))).compose(ignore -> podOperator.getAsync(namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()))).compose(pod -> {
if (KafkaConnectBuildUtils.buildPodSucceeded(pod)) {
ContainerStateTerminated state = pod.getStatus().getContainerStatuses().get(0).getState().getTerminated();
String image = state.getMessage().trim();
LOGGER.infoCr(reconciliation, "Build completed successfully. New image is {}.", image);
return Future.succeededFuture(image);
} else {
ContainerStateTerminated state = pod.getStatus().getContainerStatuses().get(0).getState().getTerminated();
LOGGER.warnCr(reconciliation, "Build failed with code {}: {}", state.getExitCode(), state.getMessage());
return Future.failedFuture("The Kafka Connect build failed");
}
});
}
use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.
the class KafkaBridgeAssemblyOperator method createOrUpdate.
@Override
protected Future<KafkaBridgeStatus> createOrUpdate(Reconciliation reconciliation, KafkaBridge assemblyResource) {
KafkaBridgeStatus kafkaBridgeStatus = new KafkaBridgeStatus();
String namespace = reconciliation.namespace();
KafkaBridgeCluster bridge;
try {
bridge = KafkaBridgeCluster.fromCrd(reconciliation, assemblyResource, versions);
} catch (Exception e) {
LOGGER.warnCr(reconciliation, e);
StatusUtils.setStatusConditionAndObservedGeneration(assemblyResource, kafkaBridgeStatus, Future.failedFuture(e));
return Future.failedFuture(new ReconciliationException(kafkaBridgeStatus, e));
}
KafkaClientAuthentication auth = assemblyResource.getSpec().getAuthentication();
List<CertSecretSource> trustedCertificates = assemblyResource.getSpec().getTls() == null ? Collections.emptyList() : assemblyResource.getSpec().getTls().getTrustedCertificates();
Promise<KafkaBridgeStatus> createOrUpdatePromise = Promise.promise();
boolean bridgeHasZeroReplicas = bridge.getReplicas() == 0;
LOGGER.debugCr(reconciliation, "Updating Kafka Bridge cluster");
kafkaBridgeServiceAccount(reconciliation, namespace, bridge).compose(i -> deploymentOperations.scaleDown(reconciliation, namespace, bridge.getName(), bridge.getReplicas())).compose(scale -> serviceOperations.reconcile(reconciliation, namespace, bridge.getServiceName(), bridge.generateService())).compose(i -> Util.metricsAndLogging(reconciliation, configMapOperations, namespace, bridge.getLogging(), null)).compose(metricsAndLogging -> configMapOperations.reconcile(reconciliation, namespace, bridge.getAncillaryConfigMapName(), bridge.generateMetricsAndLogConfigMap(metricsAndLogging))).compose(i -> pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetOperator.reconcile(reconciliation, namespace, bridge.getName(), bridge.generatePodDisruptionBudget()) : Future.succeededFuture()).compose(i -> !pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetV1Beta1Operator.reconcile(reconciliation, namespace, bridge.getName(), bridge.generatePodDisruptionBudgetV1Beta1()) : Future.succeededFuture()).compose(i -> Util.authTlsHash(secretOperations, namespace, auth, trustedCertificates)).compose(hash -> deploymentOperations.reconcile(reconciliation, namespace, bridge.getName(), bridge.generateDeployment(Collections.singletonMap(Annotations.ANNO_STRIMZI_AUTH_HASH, Integer.toString(hash)), pfa.isOpenshift(), imagePullPolicy, imagePullSecrets))).compose(i -> deploymentOperations.scaleUp(reconciliation, namespace, bridge.getName(), bridge.getReplicas())).compose(i -> deploymentOperations.waitForObserved(reconciliation, namespace, bridge.getName(), 1_000, operationTimeoutMs)).compose(i -> bridgeHasZeroReplicas ? Future.succeededFuture() : deploymentOperations.readiness(reconciliation, namespace, bridge.getName(), 1_000, operationTimeoutMs)).onComplete(reconciliationResult -> {
StatusUtils.setStatusConditionAndObservedGeneration(assemblyResource, kafkaBridgeStatus, reconciliationResult.mapEmpty());
if (!bridgeHasZeroReplicas) {
int port = KafkaBridgeCluster.DEFAULT_REST_API_PORT;
if (bridge.getHttp() != null) {
port = bridge.getHttp().getPort();
}
kafkaBridgeStatus.setUrl(KafkaBridgeResources.url(bridge.getCluster(), namespace, port));
}
kafkaBridgeStatus.setReplicas(bridge.getReplicas());
kafkaBridgeStatus.setLabelSelector(bridge.getSelectorLabels().toSelectorString());
if (reconciliationResult.succeeded()) {
createOrUpdatePromise.complete(kafkaBridgeStatus);
} else {
createOrUpdatePromise.fail(new ReconciliationException(kafkaBridgeStatus, reconciliationResult.cause()));
}
});
return createOrUpdatePromise.future();
}
use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.
the class KafkaConnectApiImpl method createOrUpdatePutRequest.
@Override
@SuppressWarnings("unchecked")
public Future<Map<String, Object>> createOrUpdatePutRequest(Reconciliation reconciliation, String host, int port, String connectorName, JsonObject configJson) {
Buffer data = configJson.toBuffer();
String path = "/connectors/" + connectorName + "/config";
LOGGER.debugCr(reconciliation, "Making PUT request to {} with body {}", path, configJson);
return HttpClientUtils.withHttpClient(vertx, new HttpClientOptions().setLogActivity(true), (httpClient, result) -> httpClient.request(HttpMethod.PUT, port, host, path, request -> {
if (request.succeeded()) {
request.result().setFollowRedirects(true).putHeader("Accept", "application/json").putHeader("Content-Type", "application/json").putHeader("Content-Length", String.valueOf(data.length())).write(data);
request.result().send(response -> {
if (response.succeeded()) {
if (response.result().statusCode() == 200 || response.result().statusCode() == 201) {
response.result().bodyHandler(buffer -> {
try {
Map t = mapper.readValue(buffer.getBytes(), Map.class);
LOGGER.debugCr(reconciliation, "Got {} response to PUT request to {}: {}", response.result().statusCode(), path, t);
result.complete(t);
} catch (IOException e) {
result.fail(new ConnectRestException(response.result(), "Could not deserialize response: " + e));
}
});
} else {
// TODO Handle 409 (Conflict) indicating a rebalance in progress
LOGGER.debugCr(reconciliation, "Got {} response to PUT request to {}", response.result().statusCode(), path);
response.result().bodyHandler(buffer -> {
JsonObject x = buffer.toJsonObject();
result.fail(new ConnectRestException(response.result(), x.getString("message")));
});
}
} else {
result.tryFail(response.cause());
}
});
} else {
result.fail(request.cause());
}
}));
}
use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.
the class StrimziPodSetController method run.
/**
* The run loop of the controller thread. It picks reconciliations from the work queue and executes them.
*/
@Override
public void run() {
LOGGER.infoOp("Starting StrimziPodSet controller for namespace {}", watchedNamespace);
LOGGER.infoOp("Waiting for informers to sync");
while (!stop && (!podInformer.hasSynced() || !strimziPodSetInformer.hasSynced() || !kafkaInformer.hasSynced())) {
// Nothing to do => just loop
}
LOGGER.infoOp("Informers are in-sync");
while (!stop) {
try {
LOGGER.debugOp("Waiting for next event from work queue");
Reconciliation reconciliation = workQueue.take().toReconciliation();
reconcile(reconciliation);
} catch (InterruptedException e) {
LOGGER.debugOp("StrimziPodSet Controller was interrupted", e);
} catch (Exception e) {
LOGGER.warnOp("StrimziPodSet reconciliation failed", e);
}
}
LOGGER.infoOp("Stopping StrimziPodSet controller");
podInformer.stop();
strimziPodSetInformer.stop();
kafkaInformer.stop();
}
use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.
the class ZookeeperScaler method connect.
/**
* Internal method used to create the Zookeeper Admin client and connect it to Zookeeper
*
* @return Future indicating success or failure
*/
private Future<ZooKeeperAdmin> connect(ZKClientConfig clientConfig) {
Promise<ZooKeeperAdmin> connected = Promise.promise();
try {
ZooKeeperAdmin zkAdmin = zooAdminProvider.createZookeeperAdmin(this.zookeeperConnectionString, zkAdminSessionTimeoutMs, watchedEvent -> LOGGER.debugCr(reconciliation, "Received event {} from ZooKeeperAdmin client connected to {}", watchedEvent, zookeeperConnectionString), clientConfig);
Util.waitFor(reconciliation, vertx, String.format("ZooKeeperAdmin connection to %s", zookeeperConnectionString), "connected", 1_000, operationTimeoutMs, () -> zkAdmin.getState().isAlive() && zkAdmin.getState().isConnected()).onSuccess(nothing -> connected.complete(zkAdmin)).onFailure(cause -> {
String message = String.format("Failed to connect to Zookeeper %s. Connection was not ready in %d ms.", zookeeperConnectionString, operationTimeoutMs);
LOGGER.warnCr(reconciliation, message);
closeConnection(zkAdmin).onComplete(nothing -> connected.fail(new ZookeeperScalingException(message, cause)));
});
} catch (IOException e) {
LOGGER.warnCr(reconciliation, "Failed to connect to {} to scale Zookeeper", zookeeperConnectionString, e);
connected.fail(new ZookeeperScalingException("Failed to connect to Zookeeper " + zookeeperConnectionString, e));
}
return connected.future();
}
Aggregations