Skip to content

Commit 57d5fbd

Browse files
authored
Make build info pluggable internally (elastic#97768)
This commit makes the Build.current() pluggable. This is only available for internal builds.
1 parent c7c1dc1 commit 57d5fbd

File tree

3 files changed

+102
-51
lines changed

3 files changed

+102
-51
lines changed

server/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@
385385
uses org.elasticsearch.jdk.ModuleQualifiedExportsService;
386386
uses org.elasticsearch.node.internal.TerminationHandlerProvider;
387387
uses org.elasticsearch.internal.VersionExtension;
388+
uses org.elasticsearch.internal.BuildExtension;
388389

389390
provides org.apache.lucene.codecs.PostingsFormat
390391
with

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

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.common.io.stream.StreamInput;
1313
import org.elasticsearch.common.io.stream.StreamOutput;
1414
import org.elasticsearch.core.Booleans;
15+
import org.elasticsearch.internal.BuildExtension;
1516

1617
import java.io.IOException;
1718
import java.net.URL;
@@ -24,61 +25,24 @@
2425
*/
2526
public record Build(Type type, String hash, String date, boolean isSnapshot, String version) {
2627

27-
private static final Build CURRENT;
28+
private static class CurrentHolder {
29+
private static final Build CURRENT = findCurrent();
2830

29-
/**
30-
* The current build of Elasticsearch. Filled with information scanned at
31-
* startup from the jar.
32-
*/
33-
public static Build current() {
34-
return CURRENT;
35-
}
36-
37-
public enum Type {
38-
39-
DEB("deb"),
40-
DOCKER("docker"),
41-
RPM("rpm"),
42-
TAR("tar"),
43-
ZIP("zip"),
44-
UNKNOWN("unknown");
45-
46-
final String displayName;
47-
48-
public String displayName() {
49-
return displayName;
50-
}
51-
52-
Type(final String displayName) {
53-
this.displayName = displayName;
54-
}
55-
56-
public static Type fromDisplayName(final String displayName, final boolean strict) {
57-
switch (displayName) {
58-
case "deb":
59-
return Type.DEB;
60-
case "docker":
61-
return Type.DOCKER;
62-
case "rpm":
63-
return Type.RPM;
64-
case "tar":
65-
return Type.TAR;
66-
case "zip":
67-
return Type.ZIP;
68-
case "unknown":
69-
return Type.UNKNOWN;
70-
default:
71-
if (strict) {
72-
throw new IllegalStateException("unexpected distribution type [" + displayName + "]; your distribution is broken");
73-
} else {
74-
return Type.UNKNOWN;
75-
}
31+
// finds the pluggable current build, or uses the local build as a fallback
32+
private static Build findCurrent() {
33+
var buildExtension = BuildExtension.load();
34+
if (buildExtension == null) {
35+
return findLocalBuild();
7636
}
37+
var build = buildExtension.getCurrentBuild();
38+
return build;
7739
}
78-
7940
}
8041

81-
static {
42+
/**
43+
* Finds build info scanned from the server jar.
44+
*/
45+
private static Build findLocalBuild() {
8246
final Type type;
8347
final String hash;
8448
final String date;
@@ -139,7 +103,55 @@ public static Type fromDisplayName(final String displayName, final boolean stric
139103
);
140104
}
141105

142-
CURRENT = new Build(type, hash, date, isSnapshot, version);
106+
return new Build(type, hash, date, isSnapshot, version);
107+
}
108+
109+
public static Build current() {
110+
return CurrentHolder.CURRENT;
111+
}
112+
113+
public enum Type {
114+
115+
DEB("deb"),
116+
DOCKER("docker"),
117+
RPM("rpm"),
118+
TAR("tar"),
119+
ZIP("zip"),
120+
UNKNOWN("unknown");
121+
122+
final String displayName;
123+
124+
public String displayName() {
125+
return displayName;
126+
}
127+
128+
Type(final String displayName) {
129+
this.displayName = displayName;
130+
}
131+
132+
public static Type fromDisplayName(final String displayName, final boolean strict) {
133+
switch (displayName) {
134+
case "deb":
135+
return Type.DEB;
136+
case "docker":
137+
return Type.DOCKER;
138+
case "rpm":
139+
return Type.RPM;
140+
case "tar":
141+
return Type.TAR;
142+
case "zip":
143+
return Type.ZIP;
144+
case "unknown":
145+
return Type.UNKNOWN;
146+
default:
147+
if (strict) {
148+
throw new IllegalStateException("unexpected distribution type [" + displayName + "]; your distribution is broken");
149+
} else {
150+
return Type.UNKNOWN;
151+
}
152+
}
153+
}
154+
143155
}
144156

145157
/**
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.internal;
10+
11+
import org.elasticsearch.Build;
12+
13+
import java.util.ServiceLoader;
14+
15+
/**
16+
* Allows plugging in current build info.
17+
*/
18+
public interface BuildExtension {
19+
20+
/**
21+
* Returns the {@link Build} that represents the running Elasticsearch code.
22+
*/
23+
Build getCurrentBuild();
24+
25+
/**
26+
* Loads a single BuildExtension, or returns {@code null} if none are found.
27+
*/
28+
static BuildExtension load() {
29+
var loader = ServiceLoader.load(BuildExtension.class);
30+
var extensions = loader.stream().toList();
31+
if (extensions.size() > 1) {
32+
throw new IllegalStateException("More than one build extension found");
33+
} else if (extensions.size() == 0) {
34+
return null;
35+
}
36+
return extensions.get(0).get();
37+
}
38+
}

0 commit comments

Comments
 (0)