Skip to content

Commit caa98cc

Browse files
committed
Initial implementation of TV checks
1 parent 2bc6284 commit caa98cc

File tree

11 files changed

+323
-0
lines changed

11 files changed

+323
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.upgrades;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.Name;
13+
import org.apache.logging.log4j.Logger;
14+
15+
public class TVBackportRollingUpgradeIT extends AbstractRollingUpgradeTestCase {
16+
17+
public TVBackportRollingUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
18+
super(upgradedNodes);
19+
}
20+
// 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.
21+
/*
22+
v2 TV1,TV3,
23+
v3 TV1,TV2,TV3,TV4
24+
25+
*/
26+
public void testTVBackport() {
27+
if (isOldCluster()) {
28+
// TODO: Implement the test for old cluster
29+
} else if (isMixedCluster()) {
30+
// TODO: Test mixed cluster behavior
31+
} else if (isUpgradedCluster()) {
32+
// TODO: Test upgraded cluster behavior
33+
} else {
34+
fail("Unknown cluster state");
35+
}
36+
}
37+
}

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
*/
3030
public class TransportVersions {
3131

32+
// If there's a next minor, it's the next minor, otherwise the next major if next major, otherwise null for main.
33+
// Probably won't ever have a patch version?
34+
public static final Integer CUTTOFF_TRANSPORT_VERSION = 8_772_0_00; // can be null for major version boundaries and main.
35+
3236
/*
3337
* NOTE: IntelliJ lies!
3438
* This map is used during class construction, referenced by the registerTransportVersion method.
@@ -323,6 +327,8 @@ static TransportVersion def(int id) {
323327
public static final TransportVersion ML_INFERENCE_ELASTIC_DENSE_TEXT_EMBEDDINGS_ADDED = def(9_109_00_0);
324328
public static final TransportVersion ML_INFERENCE_COHERE_API_VERSION = def(9_110_0_00);
325329
public static final TransportVersion ESQL_PROFILE_INCLUDE_PLAN = def(9_111_0_00);
330+
// public static final TransportVersionsGroup FOO = new TransportVersionsGroup(9_112_0_00, 3, 4,5, 2 );
331+
326332

327333
/*
328334
* STOP! READ THIS FIRST! No, really,
@@ -398,6 +404,11 @@ static TransportVersion def(int id) {
398404

399405
// the highest transport version constant defined
400406
static final TransportVersion LATEST_DEFINED;
407+
408+
static {
409+
410+
}
411+
401412
static {
402413
LATEST_DEFINED = DEFINED_VERSIONS.getLast();
403414

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch;
11+
12+
import java.util.ArrayList;
13+
import java.util.Collections;
14+
import java.util.List;
15+
16+
public class TransportVersionsGroup {
17+
public final TransportVersion localTV;
18+
public final List<TransportVersion> backportTVs;
19+
public final List<TransportVersion> futureTVs;
20+
21+
public TransportVersionsGroup(List<TransportVersion> transportVersions) {
22+
if (transportVersions.stream().sorted().toList().equals(transportVersions) == false) {
23+
throw new IllegalArgumentException("transportVersions must be sorted by version");
24+
}
25+
26+
TransportVersion currentVersion = TransportVersion.current(); // TODO this has to be set somehow
27+
28+
TransportVersion localTV = null;
29+
List<TransportVersion> backportTVs = new ArrayList<>();
30+
List<TransportVersion> futureTVs = new ArrayList<>();
31+
32+
for (TransportVersion transportVersion : transportVersions) {
33+
if (transportVersion.onOrAfter(currentVersion) == false) {
34+
futureTVs.add(transportVersion);
35+
} else if (localTV == null) {
36+
localTV = transportVersion;
37+
} else {
38+
backportTVs.add(transportVersion);
39+
}
40+
}
41+
if (localTV == null) {
42+
throw new IllegalArgumentException("TransportVersionsGroup must contain a local TransportVersion");
43+
}
44+
this.backportTVs = Collections.unmodifiableList(backportTVs);
45+
this.futureTVs = Collections.unmodifiableList(futureTVs);
46+
this.localTV = localTV;
47+
}
48+
49+
public boolean isCompatible(TransportVersion version) {
50+
return version.onOrAfter(localTV)
51+
|| backportTVs.stream().anyMatch(version::isPatchFrom);
52+
}
53+
54+
public List<Integer> getLocalAndBackportedTVIds() {
55+
var localAndBackportedTVs = new ArrayList<TransportVersion>();
56+
localAndBackportedTVs.add(localTV);
57+
localAndBackportedTVs.addAll(backportTVs);
58+
return localAndBackportedTVs.stream().map(TransportVersion::id).toList();
59+
}
60+
}

server/src/main/java/org/elasticsearch/action/ActionModule.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@
210210
import org.elasticsearch.action.termvectors.TransportMultiTermVectorsAction;
211211
import org.elasticsearch.action.termvectors.TransportShardMultiTermsVectorAction;
212212
import org.elasticsearch.action.termvectors.TransportTermVectorsAction;
213+
import org.elasticsearch.action.tvbackport.RestTVBackportAction;
214+
import org.elasticsearch.action.tvbackport.TVBackportAction;
215+
import org.elasticsearch.action.tvbackport.TransportTVBackportAction;
213216
import org.elasticsearch.action.update.TransportUpdateAction;
214217
import org.elasticsearch.client.internal.node.NodeClient;
215218
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
@@ -809,6 +812,9 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
809812
actions.register(GetSynonymRuleAction.INSTANCE, TransportGetSynonymRuleAction.class);
810813
actions.register(DeleteSynonymRuleAction.INSTANCE, TransportDeleteSynonymRuleAction.class);
811814

815+
// Transport Version Backport Testing
816+
actions.register(TVBackportAction.INSTANCE, TransportTVBackportAction.class);
817+
812818
return unmodifiableMap(actions.getRegistry());
813819
}
814820

@@ -1036,6 +1042,9 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster, Predicate<
10361042
registerHandler.accept(new RestPutSynonymRuleAction());
10371043
registerHandler.accept(new RestGetSynonymRuleAction());
10381044
registerHandler.accept(new RestDeleteSynonymRuleAction());
1045+
1046+
// Transport Version Backport Testing
1047+
registerHandler.accept(new RestTVBackportAction());
10391048
}
10401049

10411050
@Override
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.tvbackport;
11+
12+
import org.elasticsearch.client.internal.node.NodeClient;
13+
import org.elasticsearch.rest.BaseRestHandler;
14+
import org.elasticsearch.rest.RestRequest;
15+
import org.elasticsearch.rest.action.RestToXContentListener;
16+
17+
import java.io.IOException;
18+
import java.util.List;
19+
20+
public class RestTVBackportAction extends BaseRestHandler {
21+
@Override
22+
public String getName() {
23+
return "_tv_backport_action";
24+
}
25+
26+
@Override
27+
public List<Route> routes() {
28+
return List.of(new Route(RestRequest.Method.GET, "/_tv_backport"));
29+
}
30+
31+
@Override
32+
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
33+
TVBackportRequest tvBackportRequest = new TVBackportRequest();
34+
// Here you can set any parameters from the request to the tvBackportRequest if needed
35+
return channel -> client.execute(TVBackportAction.INSTANCE, tvBackportRequest, new RestToXContentListener<>(channel));
36+
}
37+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.tvbackport;
11+
12+
import org.elasticsearch.action.ActionType;
13+
14+
public class TVBackportAction extends ActionType<TVBackportResponse> {
15+
public static final TVBackportAction INSTANCE = new TVBackportAction();
16+
public static final String NAME = "cluster:monitor/tvbackport";
17+
18+
private TVBackportAction() {
19+
super(NAME);
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.tvbackport;
11+
12+
import org.elasticsearch.action.ActionRequest;
13+
import org.elasticsearch.action.ActionRequestValidationException;
14+
15+
public class TVBackportRequest extends ActionRequest {
16+
17+
@Override
18+
public ActionRequestValidationException validate() {
19+
return null;
20+
}
21+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.tvbackport;
11+
12+
import org.elasticsearch.action.ActionResponse;
13+
import org.elasticsearch.common.io.stream.StreamInput;
14+
import org.elasticsearch.common.io.stream.StreamOutput;
15+
import org.elasticsearch.versions.TestTV;
16+
import org.elasticsearch.xcontent.ToXContentObject;
17+
import org.elasticsearch.xcontent.XContentBuilder;
18+
19+
import java.io.IOException;
20+
21+
public class TVBackportResponse extends ActionResponse implements ToXContentObject {
22+
String message;
23+
String testTV;
24+
25+
public TVBackportResponse(String message, String testTV) {
26+
this.message = message;
27+
this.testTV = testTV;
28+
}
29+
30+
public TVBackportResponse(StreamInput in) throws IOException {
31+
if (TestTV.INSTANCE.isCompatible(in.getTransportVersion())) {
32+
this.testTV = in.readOptionalString();
33+
} else {
34+
this.testTV = null; // Not compatible, so we don't read it
35+
}
36+
this.message = in.readString();
37+
}
38+
39+
@Override
40+
public void writeTo(StreamOutput out) throws IOException {
41+
if (TestTV.INSTANCE.isCompatible(out.getTransportVersion())) {
42+
out.writeOptionalString(testTV);
43+
}
44+
out.writeString(message);
45+
}
46+
47+
@Override
48+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
49+
builder.startObject();
50+
if (testTV != null) {
51+
builder.field("TestTV", testTV);
52+
}
53+
builder.field("message", message);
54+
builder.endObject();
55+
return builder;
56+
}
57+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.tvbackport;
11+
12+
import org.apache.logging.log4j.LogManager;
13+
import org.apache.logging.log4j.Logger;
14+
import org.elasticsearch.action.ActionListener;
15+
import org.elasticsearch.action.support.ActionFilters;
16+
import org.elasticsearch.action.support.TransportAction;
17+
import org.elasticsearch.common.util.concurrent.EsExecutors;
18+
import org.elasticsearch.injection.guice.Inject;
19+
import org.elasticsearch.tasks.Task;
20+
import org.elasticsearch.transport.TransportService;
21+
22+
public class TransportTVBackportAction extends TransportAction<TVBackportRequest, TVBackportResponse> {
23+
private static final Logger logger = LogManager.getLogger(TransportTVBackportAction.class);
24+
25+
@Inject
26+
public TransportTVBackportAction(
27+
ActionFilters actionFilters,
28+
TransportService transportService
29+
) {
30+
super(TVBackportAction.NAME, actionFilters, transportService.getTaskManager(), EsExecutors.DIRECT_EXECUTOR_SERVICE);
31+
}
32+
33+
@Override
34+
protected void doExecute(Task task, TVBackportRequest request, ActionListener<TVBackportResponse> listener) {
35+
logger.info("Executing TVBackportAction for request");
36+
listener.onResponse(new TVBackportResponse("This is a TV Backport response", "with the testTV TVGroup"));
37+
}
38+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.versions;
11+
12+
import org.elasticsearch.TransportVersion;
13+
import org.elasticsearch.TransportVersionsGroup;
14+
15+
import java.util.List;
16+
17+
public class TestTV extends TransportVersionsGroup {
18+
private TestTV() {
19+
super(List.of(
20+
new TransportVersion(9_111_0_00), // main
21+
new TransportVersion(9_001_0_00), // 9.0
22+
new TransportVersion(8_111_0_00), //8.19
23+
new TransportVersion(8_001_0_00) // 8.18
24+
));
25+
}
26+
}

0 commit comments

Comments
 (0)