use of io.strimzi.operator.cluster.KafkaUpgradeException in project strimzi by strimzi.
the class VersionChangeCreator method detectToAndFromVersions.
/**
* Detects the current and desired Kafka versions based on the information collected from Kubernetes
*
* @return Future which completes when the "to" and "from" versions are collected
*/
private Future<Void> detectToAndFromVersions(List<Pod> pods) {
String lowestKafkaVersion = versionFromControllerResource;
String highestKafkaVersion = versionFromControllerResource;
for (Pod pod : pods) {
// Collect the different annotations from the pods
String currentVersion = Annotations.stringAnnotation(pod, ANNO_STRIMZI_IO_KAFKA_VERSION, null);
String currentMessageFormat = Annotations.stringAnnotation(pod, KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION, null);
String currentIbp = Annotations.stringAnnotation(pod, KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION, null);
// downgrades which failed in the middle and continue with them.
if (currentVersion != null) {
if (highestKafkaVersion == null) {
highestKafkaVersion = currentVersion;
} else if (compareDottedVersions(highestKafkaVersion, currentVersion) < 0) {
highestKafkaVersion = currentVersion;
}
if (lowestKafkaVersion == null) {
lowestKafkaVersion = currentVersion;
} else if (compareDottedVersions(lowestKafkaVersion, currentVersion) > 0) {
lowestKafkaVersion = currentVersion;
}
}
// upgrades or downgrades.
if (currentMessageFormat != null) {
if (highestLogMessageFormatVersionFromPods == null) {
highestLogMessageFormatVersionFromPods = currentMessageFormat;
} else if (compareDottedIVVersions(highestLogMessageFormatVersionFromPods, currentMessageFormat) < 0) {
highestLogMessageFormatVersionFromPods = currentMessageFormat;
}
}
// upgrades or downgrades.
if (currentIbp != null) {
if (highestInterBrokerProtocolVersionFromPods == null) {
highestInterBrokerProtocolVersionFromPods = currentIbp;
} else if (compareDottedIVVersions(highestInterBrokerProtocolVersionFromPods, currentIbp) < 0) {
highestInterBrokerProtocolVersionFromPods = currentIbp;
}
}
}
// describing the situation.
if (lowestKafkaVersion == null) {
if (freshDeployment && pods.isEmpty()) {
// No version found in Pods or StatefulSet because they do not exist => This means we
// are dealing with a brand new Kafka cluster or a Kafka cluster with deleted
// StatefulSet and Pods. New cluster does not need an upgrade. Cluster without
// StatefulSet / Pods cannot be rolled. So we can just deploy a new one with the desired
// version. So we can use the desired version and set the version change to noop.
versionFrom = versionFromCr;
versionTo = versionFromCr;
} else {
// Either Pods or StatefulSet already exist. However, none of them contains the version
// annotation. This suggests they are not created by the current versions of Strimzi.
// Without the annotation, we cannot detect the Kafka version and decide on upgrade.
LOGGER.warnCr(reconciliation, "Kafka Pods or StatefulSet exist, but do not contain the {} annotation to detect their version. Kafka upgrade cannot be detected.", ANNO_STRIMZI_IO_KAFKA_VERSION);
throw new KafkaUpgradeException("Kafka Pods or StatefulSet exist, but do not contain the " + ANNO_STRIMZI_IO_KAFKA_VERSION + " annotation to detect their version. Kafka upgrade cannot be detected.");
}
} else if (lowestKafkaVersion.equals(highestKafkaVersion)) {
// All brokers have the same version. We can use it as the current version.
versionFrom = versions.version(lowestKafkaVersion);
versionTo = versionFromCr;
} else if (compareDottedVersions(highestKafkaVersion, versionFromCr.version()) > 0) {
// Highest Kafka version used by the brokers is higher than desired => suspected downgrade
versionFrom = versions.version(highestKafkaVersion);
versionTo = versionFromCr;
} else {
// Highest Kafka version used by the brokers is equal or lower than desired => suspected upgrade
versionFrom = versions.version(lowestKafkaVersion);
versionTo = versionFromCr;
}
return Future.succeededFuture();
}
use of io.strimzi.operator.cluster.KafkaUpgradeException in project strimzi-kafka-operator by strimzi.
the class VersionChangeCreator method prepareVersionChange.
/**
* Plans the version change and creates a KafkaVersionChange object which contains the main versions as well as the
* inter.broker.protocol.version and log.message.format.version.
*
* @return Future with the KafkaVersionChange instance describing the Kafka version changes
*/
@SuppressWarnings("checkstyle:CyclomaticComplexity")
private Future<KafkaVersionChange> prepareVersionChange() {
if (versionFrom.compareTo(versionTo) == 0) {
// => no version change
LOGGER.debugCr(reconciliation, "{}: No Kafka version change", reconciliation);
if (interBrokerProtocolVersionFromCr == null) {
// When inter.broker.protocol.version is not set, we set it to current Kafka version
interBrokerProtocolVersion = versionFromCr.protocolVersion();
if (highestInterBrokerProtocolVersionFromPods != null && !versionFromCr.protocolVersion().equals(highestInterBrokerProtocolVersionFromPods)) {
LOGGER.infoCr(reconciliation, "Upgrading Kafka inter.broker.protocol.version from {} to {}", highestInterBrokerProtocolVersionFromPods, versionFromCr.protocolVersion());
if (compareDottedIVVersions(versionFromCr.protocolVersion(), "3.0") >= 0) {
// From Kafka 3.0.0, the log.message.format.version is ignored when inter.broker.protocol.version is set to 3.0 or higher
// We set the log.message.format.version immediately to the same version as inter.broker.protocol.version to avoid unnecessary rolling update
logMessageFormatVersion = versionFromCr.messageVersion();
} else if (logMessageFormatVersionFromCr == null && highestLogMessageFormatVersionFromPods != null) {
// For Kafka versions older than 3.0.0, inter.broker.protocol.version and log.message.format.version should not change in the same rolling
// update. When this rolling update is going to change the inter.broker.protocol.version, we keep the old log.message.format.version
logMessageFormatVersion = highestLogMessageFormatVersionFromPods;
}
}
}
if (logMessageFormatVersionFromCr == null) {
// When log.message.format.version is not set, we set it to current Kafka version
logMessageFormatVersion = versionFromCr.messageVersion();
if (highestLogMessageFormatVersionFromPods != null && !versionFromCr.messageVersion().equals(highestLogMessageFormatVersionFromPods)) {
LOGGER.infoCr(reconciliation, "Upgrading Kafka log.message.format.version from {} to {}", highestLogMessageFormatVersionFromPods, versionFromCr.messageVersion());
}
}
} else {
if (versionFrom.compareTo(versionTo) < 0) {
// => is upgrade
LOGGER.infoCr(reconciliation, "Kafka is upgrading from {} to {}", versionFrom.version(), versionTo.version());
// used by any of the brokers is not higher than the broker version we upgrade from.
if ((highestLogMessageFormatVersionFromPods != null && compareDottedIVVersions(versionFrom.messageVersion(), highestLogMessageFormatVersionFromPods) < 0) || (highestInterBrokerProtocolVersionFromPods != null && compareDottedIVVersions(versionFrom.protocolVersion(), highestInterBrokerProtocolVersionFromPods) < 0)) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used by the brokers have to be lower or equal to the Kafka broker version we upgrade from ({})", highestInterBrokerProtocolVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionFrom.version());
throw new KafkaUpgradeException("log.message.format.version (" + highestLogMessageFormatVersionFromPods + ") and inter.broker.protocol.version (" + highestInterBrokerProtocolVersionFromPods + ") used by the brokers have to be lower or equal to the Kafka broker version we upgrade from (" + versionFrom.version() + ")");
}
String desiredLogMessageFormat = logMessageFormatVersionFromCr;
String desiredInterBrokerProtocol = interBrokerProtocolVersionFromCr;
// upgrading from. If it is not set, we set it to the version we are upgrading from.
if (desiredLogMessageFormat == null || compareDottedIVVersions(versionFrom.messageVersion(), desiredLogMessageFormat) < 0) {
logMessageFormatVersion = versionFrom.messageVersion();
}
// are upgrading from. If it is not set, we set it to the version we are upgrading from.
if (desiredInterBrokerProtocol == null || compareDottedIVVersions(versionFrom.protocolVersion(), desiredInterBrokerProtocol) < 0) {
interBrokerProtocolVersion = versionFrom.protocolVersion();
}
} else {
// Has to be a downgrade
LOGGER.infoCr(reconciliation, "Kafka is downgrading from {} to {}", versionFrom.version(), versionTo.version());
// reconciliation as well.
if (highestLogMessageFormatVersionFromPods == null || compareDottedIVVersions(versionTo.messageVersion(), highestLogMessageFormatVersionFromPods) < 0 || highestInterBrokerProtocolVersionFromPods == null || compareDottedIVVersions(versionTo.protocolVersion(), highestInterBrokerProtocolVersionFromPods) < 0) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used by the brokers have to be set and be lower or equal to the Kafka broker version we downgrade to ({})", highestLogMessageFormatVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionTo.version());
throw new KafkaUpgradeException("log.message.format.version (" + highestLogMessageFormatVersionFromPods + ") and inter.broker.protocol.version (" + highestInterBrokerProtocolVersionFromPods + ") used by the brokers have to be set and be lower or equal to the Kafka broker version we downgrade to (" + versionTo.version() + ")");
}
String desiredLogMessageFormat = logMessageFormatVersionFromCr;
String desiredInterBrokerProtocol = interBrokerProtocolVersionFromCr;
// If log.message.format.version is not set, we set it to the version we are downgrading to.
if (desiredLogMessageFormat == null) {
desiredLogMessageFormat = versionTo.messageVersion();
logMessageFormatVersion = versionTo.messageVersion();
}
// If inter.broker.protocol.version is not set, we set it to the version we are downgrading to.
if (desiredInterBrokerProtocol == null) {
desiredInterBrokerProtocol = versionTo.protocolVersion();
interBrokerProtocolVersion = versionTo.protocolVersion();
}
// validation. However, we still double-check it as safety.
if (compareDottedIVVersions(versionTo.messageVersion(), desiredLogMessageFormat) < 0 || compareDottedIVVersions(versionTo.protocolVersion(), desiredInterBrokerProtocol) < 0) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used in the Kafka CR have to be set and be lower or equal to the Kafka broker version we downgrade to ({})", highestLogMessageFormatVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionTo.version());
throw new KafkaUpgradeException("log.message.format.version and inter.broker.protocol.version used in the Kafka CR have to be set and be lower or equal to the Kafka broker version we downgrade to");
}
}
}
return Future.succeededFuture(new KafkaVersionChange(versionFrom, versionTo, interBrokerProtocolVersion, logMessageFormatVersion));
}
use of io.strimzi.operator.cluster.KafkaUpgradeException in project strimzi-kafka-operator by strimzi.
the class VersionChangeCreator method detectToAndFromVersions.
/**
* Detects the current and desired Kafka versions based on the information collected from Kubernetes
*
* @return Future which completes when the "to" and "from" versions are collected
*/
private Future<Void> detectToAndFromVersions(List<Pod> pods) {
String lowestKafkaVersion = versionFromControllerResource;
String highestKafkaVersion = versionFromControllerResource;
for (Pod pod : pods) {
// Collect the different annotations from the pods
String currentVersion = Annotations.stringAnnotation(pod, ANNO_STRIMZI_IO_KAFKA_VERSION, null);
String currentMessageFormat = Annotations.stringAnnotation(pod, KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION, null);
String currentIbp = Annotations.stringAnnotation(pod, KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION, null);
// downgrades which failed in the middle and continue with them.
if (currentVersion != null) {
if (highestKafkaVersion == null) {
highestKafkaVersion = currentVersion;
} else if (compareDottedVersions(highestKafkaVersion, currentVersion) < 0) {
highestKafkaVersion = currentVersion;
}
if (lowestKafkaVersion == null) {
lowestKafkaVersion = currentVersion;
} else if (compareDottedVersions(lowestKafkaVersion, currentVersion) > 0) {
lowestKafkaVersion = currentVersion;
}
}
// upgrades or downgrades.
if (currentMessageFormat != null) {
if (highestLogMessageFormatVersionFromPods == null) {
highestLogMessageFormatVersionFromPods = currentMessageFormat;
} else if (compareDottedIVVersions(highestLogMessageFormatVersionFromPods, currentMessageFormat) < 0) {
highestLogMessageFormatVersionFromPods = currentMessageFormat;
}
}
// upgrades or downgrades.
if (currentIbp != null) {
if (highestInterBrokerProtocolVersionFromPods == null) {
highestInterBrokerProtocolVersionFromPods = currentIbp;
} else if (compareDottedIVVersions(highestInterBrokerProtocolVersionFromPods, currentIbp) < 0) {
highestInterBrokerProtocolVersionFromPods = currentIbp;
}
}
}
// describing the situation.
if (lowestKafkaVersion == null) {
if (freshDeployment && pods.isEmpty()) {
// No version found in Pods or StatefulSet because they do not exist => This means we
// are dealing with a brand new Kafka cluster or a Kafka cluster with deleted
// StatefulSet and Pods. New cluster does not need an upgrade. Cluster without
// StatefulSet / Pods cannot be rolled. So we can just deploy a new one with the desired
// version. So we can use the desired version and set the version change to noop.
versionFrom = versionFromCr;
versionTo = versionFromCr;
} else {
// Either Pods or StatefulSet already exist. However, none of them contains the version
// annotation. This suggests they are not created by the current versions of Strimzi.
// Without the annotation, we cannot detect the Kafka version and decide on upgrade.
LOGGER.warnCr(reconciliation, "Kafka Pods or StatefulSet exist, but do not contain the {} annotation to detect their version. Kafka upgrade cannot be detected.", ANNO_STRIMZI_IO_KAFKA_VERSION);
throw new KafkaUpgradeException("Kafka Pods or StatefulSet exist, but do not contain the " + ANNO_STRIMZI_IO_KAFKA_VERSION + " annotation to detect their version. Kafka upgrade cannot be detected.");
}
} else if (lowestKafkaVersion.equals(highestKafkaVersion)) {
// All brokers have the same version. We can use it as the current version.
versionFrom = versions.version(lowestKafkaVersion);
versionTo = versionFromCr;
} else if (compareDottedVersions(highestKafkaVersion, versionFromCr.version()) > 0) {
// Highest Kafka version used by the brokers is higher than desired => suspected downgrade
versionFrom = versions.version(highestKafkaVersion);
versionTo = versionFromCr;
} else {
// Highest Kafka version used by the brokers is equal or lower than desired => suspected upgrade
versionFrom = versions.version(lowestKafkaVersion);
versionTo = versionFromCr;
}
return Future.succeededFuture();
}
use of io.strimzi.operator.cluster.KafkaUpgradeException in project strimzi by strimzi.
the class VersionChangeCreator method prepareVersionChange.
/**
* Plans the version change and creates a KafkaVersionChange object which contains the main versions as well as the
* inter.broker.protocol.version and log.message.format.version.
*
* @return Future with the KafkaVersionChange instance describing the Kafka version changes
*/
@SuppressWarnings("checkstyle:CyclomaticComplexity")
private Future<KafkaVersionChange> prepareVersionChange() {
if (versionFrom.compareTo(versionTo) == 0) {
// => no version change
LOGGER.debugCr(reconciliation, "{}: No Kafka version change", reconciliation);
if (interBrokerProtocolVersionFromCr == null) {
// When inter.broker.protocol.version is not set, we set it to current Kafka version
interBrokerProtocolVersion = versionFromCr.protocolVersion();
if (highestInterBrokerProtocolVersionFromPods != null && !versionFromCr.protocolVersion().equals(highestInterBrokerProtocolVersionFromPods)) {
LOGGER.infoCr(reconciliation, "Upgrading Kafka inter.broker.protocol.version from {} to {}", highestInterBrokerProtocolVersionFromPods, versionFromCr.protocolVersion());
if (compareDottedIVVersions(versionFromCr.protocolVersion(), "3.0") >= 0) {
// From Kafka 3.0.0, the log.message.format.version is ignored when inter.broker.protocol.version is set to 3.0 or higher
// We set the log.message.format.version immediately to the same version as inter.broker.protocol.version to avoid unnecessary rolling update
logMessageFormatVersion = versionFromCr.messageVersion();
} else if (logMessageFormatVersionFromCr == null && highestLogMessageFormatVersionFromPods != null) {
// For Kafka versions older than 3.0.0, inter.broker.protocol.version and log.message.format.version should not change in the same rolling
// update. When this rolling update is going to change the inter.broker.protocol.version, we keep the old log.message.format.version
logMessageFormatVersion = highestLogMessageFormatVersionFromPods;
}
}
}
if (logMessageFormatVersionFromCr == null) {
// When log.message.format.version is not set, we set it to current Kafka version
logMessageFormatVersion = versionFromCr.messageVersion();
if (highestLogMessageFormatVersionFromPods != null && !versionFromCr.messageVersion().equals(highestLogMessageFormatVersionFromPods)) {
LOGGER.infoCr(reconciliation, "Upgrading Kafka log.message.format.version from {} to {}", highestLogMessageFormatVersionFromPods, versionFromCr.messageVersion());
}
}
} else {
if (versionFrom.compareTo(versionTo) < 0) {
// => is upgrade
LOGGER.infoCr(reconciliation, "Kafka is upgrading from {} to {}", versionFrom.version(), versionTo.version());
// used by any of the brokers is not higher than the broker version we upgrade from.
if ((highestLogMessageFormatVersionFromPods != null && compareDottedIVVersions(versionFrom.messageVersion(), highestLogMessageFormatVersionFromPods) < 0) || (highestInterBrokerProtocolVersionFromPods != null && compareDottedIVVersions(versionFrom.protocolVersion(), highestInterBrokerProtocolVersionFromPods) < 0)) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used by the brokers have to be lower or equal to the Kafka broker version we upgrade from ({})", highestInterBrokerProtocolVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionFrom.version());
throw new KafkaUpgradeException("log.message.format.version (" + highestLogMessageFormatVersionFromPods + ") and inter.broker.protocol.version (" + highestInterBrokerProtocolVersionFromPods + ") used by the brokers have to be lower or equal to the Kafka broker version we upgrade from (" + versionFrom.version() + ")");
}
String desiredLogMessageFormat = logMessageFormatVersionFromCr;
String desiredInterBrokerProtocol = interBrokerProtocolVersionFromCr;
// upgrading from. If it is not set, we set it to the version we are upgrading from.
if (desiredLogMessageFormat == null || compareDottedIVVersions(versionFrom.messageVersion(), desiredLogMessageFormat) < 0) {
logMessageFormatVersion = versionFrom.messageVersion();
}
// are upgrading from. If it is not set, we set it to the version we are upgrading from.
if (desiredInterBrokerProtocol == null || compareDottedIVVersions(versionFrom.protocolVersion(), desiredInterBrokerProtocol) < 0) {
interBrokerProtocolVersion = versionFrom.protocolVersion();
}
} else {
// Has to be a downgrade
LOGGER.infoCr(reconciliation, "Kafka is downgrading from {} to {}", versionFrom.version(), versionTo.version());
// reconciliation as well.
if (highestLogMessageFormatVersionFromPods == null || compareDottedIVVersions(versionTo.messageVersion(), highestLogMessageFormatVersionFromPods) < 0 || highestInterBrokerProtocolVersionFromPods == null || compareDottedIVVersions(versionTo.protocolVersion(), highestInterBrokerProtocolVersionFromPods) < 0) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used by the brokers have to be set and be lower or equal to the Kafka broker version we downgrade to ({})", highestLogMessageFormatVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionTo.version());
throw new KafkaUpgradeException("log.message.format.version (" + highestLogMessageFormatVersionFromPods + ") and inter.broker.protocol.version (" + highestInterBrokerProtocolVersionFromPods + ") used by the brokers have to be set and be lower or equal to the Kafka broker version we downgrade to (" + versionTo.version() + ")");
}
String desiredLogMessageFormat = logMessageFormatVersionFromCr;
String desiredInterBrokerProtocol = interBrokerProtocolVersionFromCr;
// If log.message.format.version is not set, we set it to the version we are downgrading to.
if (desiredLogMessageFormat == null) {
desiredLogMessageFormat = versionTo.messageVersion();
logMessageFormatVersion = versionTo.messageVersion();
}
// If inter.broker.protocol.version is not set, we set it to the version we are downgrading to.
if (desiredInterBrokerProtocol == null) {
desiredInterBrokerProtocol = versionTo.protocolVersion();
interBrokerProtocolVersion = versionTo.protocolVersion();
}
// validation. However, we still double-check it as safety.
if (compareDottedIVVersions(versionTo.messageVersion(), desiredLogMessageFormat) < 0 || compareDottedIVVersions(versionTo.protocolVersion(), desiredInterBrokerProtocol) < 0) {
LOGGER.warnCr(reconciliation, "log.message.format.version ({}) and inter.broker.protocol.version ({}) used in the Kafka CR have to be set and be lower or equal to the Kafka broker version we downgrade to ({})", highestLogMessageFormatVersionFromPods, highestInterBrokerProtocolVersionFromPods, versionTo.version());
throw new KafkaUpgradeException("log.message.format.version and inter.broker.protocol.version used in the Kafka CR have to be set and be lower or equal to the Kafka broker version we downgrade to");
}
}
}
return Future.succeededFuture(new KafkaVersionChange(versionFrom, versionTo, interBrokerProtocolVersion, logMessageFormatVersion));
}
Aggregations