Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.upgrades;

import com.carrotsearch.randomizedtesting.annotations.Name;

public class TVBackportRollingUpgradeIT extends AbstractRollingUpgradeTestCase {

public TVBackportRollingUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
super(upgradedNodes);
}

// We'd be most interested to see this failing on the patch issue where 9.0 thinks it's ahead of 8.x but it's not.
/*
v2 TV1,TV3,
v3 TV1,TV2,TV3,TV4

*/
public void testTVBackport() {
if (isOldCluster()) {
// TODO: Implement the test for old cluster
} else if (isMixedCluster()) {
// TODO: Test mixed cluster behavior
} else if (isUpgradedCluster()) {
// TODO: Test upgraded cluster behavior
} else {
fail("Unknown cluster state");
}
}
}
10 changes: 10 additions & 0 deletions server/src/main/java/org/elasticsearch/TransportVersions.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
*/
public class TransportVersions {

// If there's a next minor, it's the next minor, otherwise the next major if next major, otherwise null for main.
// Probably won't ever have a patch version?
public static final Integer CUTTOFF_TRANSPORT_VERSION = 8_772_0_00; // can be null for major version boundaries and main.

/*
* NOTE: IntelliJ lies!
* This map is used during class construction, referenced by the registerTransportVersion method.
Expand Down Expand Up @@ -323,6 +327,7 @@ static TransportVersion def(int id) {
public static final TransportVersion ML_INFERENCE_ELASTIC_DENSE_TEXT_EMBEDDINGS_ADDED = def(9_109_00_0);
public static final TransportVersion ML_INFERENCE_COHERE_API_VERSION = def(9_110_0_00);
public static final TransportVersion ESQL_PROFILE_INCLUDE_PLAN = def(9_111_0_00);
// public static final TransportVersionsGroup FOO = new TransportVersionsGroup(9_112_0_00, 3, 4,5, 2 );

/*
* STOP! READ THIS FIRST! No, really,
Expand Down Expand Up @@ -398,6 +403,11 @@ static TransportVersion def(int id) {

// the highest transport version constant defined
static final TransportVersion LATEST_DEFINED;

static {

}

static {
LATEST_DEFINED = DEFINED_VERSIONS.getLast();

Expand Down
59 changes: 59 additions & 0 deletions server/src/main/java/org/elasticsearch/TransportVersionsGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TransportVersionsGroup {
public final TransportVersion localTV;
public final List<TransportVersion> backportTVs;
public final List<TransportVersion> futureTVs;

public TransportVersionsGroup(List<TransportVersion> transportVersions) {
if (transportVersions.stream().sorted().toList().equals(transportVersions) == false) {
throw new IllegalArgumentException("transportVersions must be sorted by version");
}

TransportVersion currentVersion = TransportVersion.current(); // TODO this has to be set somehow

TransportVersion localTV = null;
List<TransportVersion> backportTVs = new ArrayList<>();
List<TransportVersion> futureTVs = new ArrayList<>();

for (TransportVersion transportVersion : transportVersions) {
if (transportVersion.onOrAfter(currentVersion) == false) {
futureTVs.add(transportVersion);
} else if (localTV == null) {
localTV = transportVersion;
} else {
backportTVs.add(transportVersion);
}
}
if (localTV == null) {
throw new IllegalArgumentException("TransportVersionsGroup must contain a local TransportVersion");
}
this.backportTVs = Collections.unmodifiableList(backportTVs);
this.futureTVs = Collections.unmodifiableList(futureTVs);
this.localTV = localTV;
}

public boolean isCompatible(TransportVersion version) {
return version.onOrAfter(localTV) || backportTVs.stream().anyMatch(version::isPatchFrom);
}

public List<Integer> getLocalAndBackportedTVIds() {
var localAndBackportedTVs = new ArrayList<TransportVersion>();
localAndBackportedTVs.add(localTV);
localAndBackportedTVs.addAll(backportTVs);
return localAndBackportedTVs.stream().map(TransportVersion::id).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@
import org.elasticsearch.action.termvectors.TransportMultiTermVectorsAction;
import org.elasticsearch.action.termvectors.TransportShardMultiTermsVectorAction;
import org.elasticsearch.action.termvectors.TransportTermVectorsAction;
import org.elasticsearch.action.tvbackport.RestTVBackportAction;
import org.elasticsearch.action.tvbackport.TVBackportAction;
import org.elasticsearch.action.tvbackport.TransportTVBackportAction;
import org.elasticsearch.action.update.TransportUpdateAction;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
Expand Down Expand Up @@ -809,6 +812,9 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
actions.register(GetSynonymRuleAction.INSTANCE, TransportGetSynonymRuleAction.class);
actions.register(DeleteSynonymRuleAction.INSTANCE, TransportDeleteSynonymRuleAction.class);

// Transport Version Backport Testing
actions.register(TVBackportAction.INSTANCE, TransportTVBackportAction.class);

return unmodifiableMap(actions.getRegistry());
}

Expand Down Expand Up @@ -1036,6 +1042,9 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster, Predicate<
registerHandler.accept(new RestPutSynonymRuleAction());
registerHandler.accept(new RestGetSynonymRuleAction());
registerHandler.accept(new RestDeleteSynonymRuleAction());

// Transport Version Backport Testing
registerHandler.accept(new RestTVBackportAction());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.tvbackport;

import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;

import java.io.IOException;
import java.util.List;

public class RestTVBackportAction extends BaseRestHandler {
@Override
public String getName() {
return "_tv_backport_action";
}

@Override
public List<Route> routes() {
return List.of(new Route(RestRequest.Method.GET, "/_tv_backport"));
}

@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
TVBackportRequest tvBackportRequest = new TVBackportRequest();
// Here you can set any parameters from the request to the tvBackportRequest if needed
return channel -> client.execute(TVBackportAction.INSTANCE, tvBackportRequest, new RestToXContentListener<>(channel));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.tvbackport;

import org.elasticsearch.action.ActionType;

public class TVBackportAction extends ActionType<TVBackportResponse> {
public static final TVBackportAction INSTANCE = new TVBackportAction();
public static final String NAME = "cluster:monitor/tvbackport";

private TVBackportAction() {
super(NAME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.tvbackport;

import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

public class TVBackportRequest extends ActionRequest {

@Override
public ActionRequestValidationException validate() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.tvbackport;

import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.versions.TestTV;
import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;

public class TVBackportResponse extends ActionResponse implements ToXContentObject {
String message;
String testTV;

public TVBackportResponse(String message, String testTV) {
this.message = message;
this.testTV = testTV;
}

public TVBackportResponse(StreamInput in) throws IOException {
if (TestTV.INSTANCE.isCompatible(in.getTransportVersion())) {
this.testTV = in.readOptionalString();
} else {
this.testTV = null; // Not compatible, so we don't read it
}
this.message = in.readString();
}

@Override
public void writeTo(StreamOutput out) throws IOException {
if (TestTV.INSTANCE.isCompatible(out.getTransportVersion())) {
out.writeOptionalString(testTV);
}
out.writeString(message);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (testTV != null) {
builder.field("TestTV", testTV);
}
builder.field("message", message);
builder.endObject();
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.tvbackport;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.transport.TransportService;

public class TransportTVBackportAction extends TransportAction<TVBackportRequest, TVBackportResponse> {
private static final Logger logger = LogManager.getLogger(TransportTVBackportAction.class);

@Inject
public TransportTVBackportAction(ActionFilters actionFilters, TransportService transportService) {
super(TVBackportAction.NAME, actionFilters, transportService.getTaskManager(), EsExecutors.DIRECT_EXECUTOR_SERVICE);
}

@Override
protected void doExecute(Task task, TVBackportRequest request, ActionListener<TVBackportResponse> listener) {
logger.info("Executing TVBackportAction for request");
listener.onResponse(new TVBackportResponse("This is a TV Backport response", "with the testTV TVGroup"));
}
}
28 changes: 28 additions & 0 deletions server/src/main/java/org/elasticsearch/versions/TestTV.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.versions;

import org.elasticsearch.TransportVersion;
import org.elasticsearch.TransportVersionsGroup;

import java.util.List;

public class TestTV extends TransportVersionsGroup {
private TestTV() {
super(
List.of(
new TransportVersion(9_111_0_00), // main
new TransportVersion(9_001_0_00), // 9.0
new TransportVersion(8_111_0_00), // 8.19
new TransportVersion(8_001_0_00) // 8.18
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ public void testIsPatchFrom() {
assertThat(TransportVersion.fromId(8_800_0_49).isPatchFrom(patchVersion), is(true));
assertThat(TransportVersion.fromId(8_800_1_00).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(8_801_0_00).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_000_0_03).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_000_0_04).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_000_0_05).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_100_0_03).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_100_0_04).isPatchFrom(patchVersion), is(false));
assertThat(TransportVersion.fromId(9_100_0_05).isPatchFrom(patchVersion), is(false));
}

public void testVersionConstantPresent() {
Expand Down