org.elasticsearch.license.StartBasicClusterTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of x-pack-core Show documentation
Show all versions of x-pack-core Show documentation
Elasticsearch Expanded Pack Plugin - Core
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.license;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateTaskExecutor;
import org.elasticsearch.cluster.ClusterStateTaskListener;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.license.internal.TrialLicenseVersion;
import org.elasticsearch.xpack.core.XPackPlugin;
import java.time.Clock;
import java.util.Map;
import java.util.UUID;
public class StartBasicClusterTask implements ClusterStateTaskListener {
private static final String ACKNOWLEDGEMENT_HEADER = "This license update requires acknowledgement. To acknowledge the license, "
+ "please read the following messages and call /start_basic again, this time with the \"acknowledge=true\" parameter:";
private final Logger logger;
private final String clusterName;
private final PostStartBasicRequest request;
private final String description;
private final ActionListener listener;
private final Clock clock;
StartBasicClusterTask(
Logger logger,
String clusterName,
Clock clock,
PostStartBasicRequest request,
String description,
ActionListener listener
) {
this.logger = logger;
this.clusterName = clusterName;
this.request = request;
this.description = description;
this.listener = listener;
this.clock = clock;
}
public LicensesMetadata execute(
LicensesMetadata currentLicensesMetadata,
ClusterStateTaskExecutor.TaskContext taskContext
) throws Exception {
assert taskContext.getTask() == this;
final var listener = ActionListener.runBefore(
this.listener,
() -> logger.debug("license prior to starting basic license: {}", currentLicensesMetadata)
);
License currentLicense = LicensesMetadata.extractLicense(currentLicensesMetadata);
final LicensesMetadata updatedLicensesMetadata;
if (shouldGenerateNewBasicLicense(currentLicense)) {
License selfGeneratedLicense = generateBasicLicense();
if (request.isAcknowledged() == false && currentLicense != null) {
Map ackMessageMap = LicenseUtils.getAckMessages(selfGeneratedLicense, currentLicense);
if (ackMessageMap.isEmpty() == false) {
taskContext.success(
() -> listener.onResponse(
new PostStartBasicResponse(
PostStartBasicResponse.Status.NEED_ACKNOWLEDGEMENT,
ackMessageMap,
ACKNOWLEDGEMENT_HEADER
)
)
);
return currentLicensesMetadata;
}
}
TrialLicenseVersion trialVersion = currentLicensesMetadata != null ? currentLicensesMetadata.getMostRecentTrialVersion() : null;
updatedLicensesMetadata = new LicensesMetadata(selfGeneratedLicense, trialVersion);
} else {
updatedLicensesMetadata = currentLicensesMetadata;
}
final var newLicenseGenerated = updatedLicensesMetadata != currentLicensesMetadata;
final var responseStatus = newLicenseGenerated
? PostStartBasicResponse.Status.GENERATED_BASIC
: PostStartBasicResponse.Status.ALREADY_USING_BASIC;
taskContext.success(() -> listener.onResponse(new PostStartBasicResponse(responseStatus)));
return updatedLicensesMetadata;
}
@Override
public void onFailure(@Nullable Exception e) {
logger.error(() -> "unexpected failure during [" + description + "]", e);
listener.onFailure(e);
}
private static boolean shouldGenerateNewBasicLicense(License currentLicense) {
return currentLicense == null
|| License.LicenseType.isBasic(currentLicense.type()) == false
|| LicenseSettings.SELF_GENERATED_LICENSE_MAX_NODES != currentLicense.maxNodes()
|| LicenseSettings.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS != LicenseUtils.getExpiryDate(currentLicense);
}
private License generateBasicLicense() {
final License.Builder specBuilder = License.builder()
.uid(UUID.randomUUID().toString())
.issuedTo(clusterName)
.maxNodes(LicenseSettings.SELF_GENERATED_LICENSE_MAX_NODES)
.issueDate(clock.millis())
.type(License.LicenseType.BASIC)
.expiryDate(LicenseSettings.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS);
return SelfGeneratedLicense.create(specBuilder);
}
public String getDescription() {
return description;
}
static class Executor implements ClusterStateTaskExecutor {
@Override
public ClusterState execute(BatchExecutionContext batchExecutionContext) throws Exception {
final var initialState = batchExecutionContext.initialState();
XPackPlugin.checkReadyForXPackCustomMetadata(initialState);
final LicensesMetadata originalLicensesMetadata = initialState.metadata().custom(LicensesMetadata.TYPE);
var currentLicensesMetadata = originalLicensesMetadata;
for (final var taskContext : batchExecutionContext.taskContexts()) {
try (var ignored = taskContext.captureResponseHeaders()) {
currentLicensesMetadata = taskContext.getTask().execute(currentLicensesMetadata, taskContext);
}
}
if (currentLicensesMetadata == originalLicensesMetadata) {
return initialState;
} else {
return ClusterState.builder(initialState)
.metadata(Metadata.builder(initialState.metadata()).putCustom(LicensesMetadata.TYPE, currentLicensesMetadata))
.build();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy