Skip to content

Commit 47f53be

Browse files
committed
Merge branch 'main' into flaky
2 parents 7682fe7 + 708d4df commit 47f53be

File tree

33 files changed

+1412
-64
lines changed

33 files changed

+1412
-64
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1515
- GHA to verify checklist items completion in PR descriptions ([#10800](https://github.com/opensearch-project/OpenSearch/pull/10800))
1616
- Allow to pass the list settings through environment variables (like [], ["a", "b", "c"], ...) ([#10625](https://github.com/opensearch-project/OpenSearch/pull/10625))
1717
- [Admission Control] Integrate CPU AC with ResourceUsageCollector and add CPU AC stats to nodes/stats ([#10887](https://github.com/opensearch-project/OpenSearch/pull/10887))
18+
- Add support for dependencies in plugin descriptor properties with semver range ([#11441](https://github.com/opensearch-project/OpenSearch/pull/11441))
1819
- [S3 Repository] Add setting to control connection count for sync client ([#12028](https://github.com/opensearch-project/OpenSearch/pull/12028))
1920

2021
### Dependencies

buildSrc/src/main/java/org/opensearch/gradle/RepositoriesSetupPlugin.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public static void configureRepositories(Project project) {
9494
String revision = matcher.group(1);
9595
MavenArtifactRepository luceneRepo = repos.maven(repo -> {
9696
repo.setName("lucene-snapshots");
97-
repo.setUrl("https://artifacts.opensearch.org/snapshots/lucene/");
97+
repo.setUrl("https://ci.opensearch.org/ci/dbc/snapshots/lucene/");
9898
});
9999
repos.exclusiveContent(exclusiveRepo -> {
100100
exclusiveRepo.filter(

distribution/tools/plugin-cli/src/main/java/org/opensearch/plugins/ListPluginsCommand.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,14 @@ private void printPlugin(Environment env, Terminal terminal, Path plugin, String
7878
PluginInfo info = PluginInfo.readFromProperties(env.pluginsDir().resolve(plugin));
7979
terminal.println(Terminal.Verbosity.SILENT, prefix + info.getName());
8080
terminal.println(Terminal.Verbosity.VERBOSE, info.toString(prefix));
81-
if (info.getOpenSearchVersion().equals(Version.CURRENT) == false) {
81+
if (!PluginsService.isPluginVersionCompatible(info, Version.CURRENT)) {
8282
terminal.errorPrintln(
8383
"WARNING: plugin ["
8484
+ info.getName()
8585
+ "] was built for OpenSearch version "
86-
+ info.getVersion()
87-
+ " but version "
86+
+ info.getOpenSearchVersionRangesString()
87+
+ " and is not compatible with "
8888
+ Version.CURRENT
89-
+ " is required"
9089
);
9190
}
9291
}

distribution/tools/plugin-cli/src/test/java/org/opensearch/plugins/InstallPluginCommandTests.java

+57
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@
7070
import org.opensearch.core.util.FileSystemUtils;
7171
import org.opensearch.env.Environment;
7272
import org.opensearch.env.TestEnvironment;
73+
import org.opensearch.semver.SemverRange;
7374
import org.opensearch.test.OpenSearchTestCase;
7475
import org.opensearch.test.PosixPermissionsResetter;
76+
import org.opensearch.test.VersionUtils;
7577
import org.junit.After;
7678
import org.junit.Before;
7779

@@ -284,6 +286,35 @@ static void writePlugin(String name, Path structure, String... additionalProps)
284286
writeJar(structure.resolve("plugin.jar"), className);
285287
}
286288

289+
static void writePlugin(String name, Path structure, SemverRange opensearchVersionRange, String... additionalProps) throws IOException {
290+
String[] properties = Stream.concat(
291+
Stream.of(
292+
"description",
293+
"fake desc",
294+
"name",
295+
name,
296+
"version",
297+
"1.0",
298+
"dependencies",
299+
"{opensearch:\"" + opensearchVersionRange + "\"}",
300+
"java.version",
301+
System.getProperty("java.specification.version"),
302+
"classname",
303+
"FakePlugin"
304+
),
305+
Arrays.stream(additionalProps)
306+
).toArray(String[]::new);
307+
PluginTestUtil.writePluginProperties(structure, properties);
308+
String className = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1) + "Plugin";
309+
writeJar(structure.resolve("plugin.jar"), className);
310+
}
311+
312+
static Path createPlugin(String name, Path structure, SemverRange opensearchVersionRange, String... additionalProps)
313+
throws IOException {
314+
writePlugin(name, structure, opensearchVersionRange, additionalProps);
315+
return writeZip(structure, null);
316+
}
317+
287318
static void writePluginSecurityPolicy(Path pluginDir, String... permissions) throws IOException {
288319
StringBuilder securityPolicyContent = new StringBuilder("grant {\n ");
289320
for (String permission : permissions) {
@@ -867,6 +898,32 @@ public void testInstallMisspelledOfficialPlugins() throws Exception {
867898
assertThat(e.getMessage(), containsString("Unknown plugin unknown_plugin"));
868899
}
869900

901+
public void testInstallPluginWithCompatibleDependencies() throws Exception {
902+
Tuple<Path, Environment> env = createEnv(fs, temp);
903+
Path pluginDir = createPluginDir(temp);
904+
String pluginZip = createPlugin("fake", pluginDir, SemverRange.fromString("~" + Version.CURRENT.toString())).toUri()
905+
.toURL()
906+
.toString();
907+
skipJarHellCommand.execute(terminal, Collections.singletonList(pluginZip), false, env.v2());
908+
assertThat(terminal.getOutput(), containsString("100%"));
909+
}
910+
911+
public void testInstallPluginWithIncompatibleDependencies() throws Exception {
912+
Tuple<Path, Environment> env = createEnv(fs, temp);
913+
Path pluginDir = createPluginDir(temp);
914+
// Core version is behind plugin version by one w.r.t patch, hence incompatible
915+
Version coreVersion = Version.CURRENT;
916+
Version pluginVersion = VersionUtils.getVersion(coreVersion.major, coreVersion.minor, (byte) (coreVersion.revision + 1));
917+
String pluginZip = createPlugin("fake", pluginDir, SemverRange.fromString("~" + pluginVersion.toString())).toUri()
918+
.toURL()
919+
.toString();
920+
IllegalArgumentException e = expectThrows(
921+
IllegalArgumentException.class,
922+
() -> skipJarHellCommand.execute(terminal, Collections.singletonList(pluginZip), false, env.v2())
923+
);
924+
assertThat(e.getMessage(), containsString("Plugin [fake] was built for OpenSearch version ~" + pluginVersion));
925+
}
926+
870927
public void testBatchFlag() throws Exception {
871928
MockTerminal terminal = new MockTerminal();
872929
installPlugin(terminal, true);

distribution/tools/plugin-cli/src/test/java/org/opensearch/plugins/ListPluginsCommandTests.java

+38-1
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,49 @@ public void testExistingIncompatiblePlugin() throws Exception {
278278
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
279279

280280
MockTerminal terminal = listPlugins(home);
281-
String message = "plugin [fake_plugin1] was built for OpenSearch version 1.0 but version " + Version.CURRENT + " is required";
281+
String message = "plugin [fake_plugin1] was built for OpenSearch version 5.0.0 and is not compatible with " + Version.CURRENT;
282282
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
283283
assertEquals("WARNING: " + message + "\n", terminal.getErrorOutput());
284284

285285
String[] params = { "-s" };
286286
terminal = listPlugins(home, params);
287287
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
288288
}
289+
290+
public void testPluginWithDependencies() throws Exception {
291+
PluginTestUtil.writePluginProperties(
292+
env.pluginsDir().resolve("fake_plugin1"),
293+
"description",
294+
"fake desc 1",
295+
"name",
296+
"fake_plugin1",
297+
"version",
298+
"1.0",
299+
"dependencies",
300+
"{opensearch:\"" + Version.CURRENT + "\"}",
301+
"java.version",
302+
System.getProperty("java.specification.version"),
303+
"classname",
304+
"org.fake1"
305+
);
306+
String[] params = { "-v" };
307+
MockTerminal terminal = listPlugins(home, params);
308+
assertEquals(
309+
buildMultiline(
310+
"Plugins directory: " + env.pluginsDir(),
311+
"fake_plugin1",
312+
"- Plugin information:",
313+
"Name: fake_plugin1",
314+
"Description: fake desc 1",
315+
"Version: 1.0",
316+
"OpenSearch Version: " + Version.CURRENT.toString(),
317+
"Java Version: " + System.getProperty("java.specification.version"),
318+
"Native Controller: false",
319+
"Extended Plugins: []",
320+
" * Classname: org.fake1",
321+
"Folder name: null"
322+
),
323+
terminal.getOutput()
324+
);
325+
}
289326
}

gradle/code-coverage.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ repositories {
1313
gradlePluginPortal()
1414
// TODO: Find the way to use the repositories from RepositoriesSetupPlugin
1515
maven {
16-
url = "https://artifacts.opensearch.org/snapshots/lucene/"
16+
url = "https://ci.opensearch.org/ci/dbc/snapshots/lucene/"
1717
}
1818
}
1919

@@ -37,14 +37,14 @@ tasks.withType(JacocoReport).configureEach {
3737
if (System.getProperty("tests.coverage")) {
3838
reporting {
3939
reports {
40-
testCodeCoverageReport(JacocoCoverageReport) {
40+
testCodeCoverageReport(JacocoCoverageReport) {
4141
testType = TestSuiteType.UNIT_TEST
4242
}
4343
}
4444
}
4545

4646
// Attach code coverage report task to Gradle check task
4747
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME).configure {
48-
dependsOn tasks.named('testCodeCoverageReport', JacocoReport)
48+
dependsOn tasks.named('testCodeCoverageReport', JacocoReport)
4949
}
5050
}

libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamInput.java

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.opensearch.core.concurrency.OpenSearchRejectedExecutionException;
5757
import org.opensearch.core.xcontent.MediaType;
5858
import org.opensearch.core.xcontent.MediaTypeRegistry;
59+
import org.opensearch.semver.SemverRange;
5960

6061
import java.io.ByteArrayInputStream;
6162
import java.io.EOFException;
@@ -750,6 +751,8 @@ public Object readGenericValue() throws IOException {
750751
return readCollection(StreamInput::readGenericValue, HashSet::new, Collections.emptySet());
751752
case 26:
752753
return readBigInteger();
754+
case 27:
755+
return readSemverRange();
753756
default:
754757
throw new IOException("Can't read unknown type [" + type + "]");
755758
}
@@ -1090,6 +1093,10 @@ public Version readVersion() throws IOException {
10901093
return Version.fromId(readVInt());
10911094
}
10921095

1096+
public SemverRange readSemverRange() throws IOException {
1097+
return SemverRange.fromString(readString());
1098+
}
1099+
10931100
/** Reads the {@link Version} from the input stream */
10941101
public Build readBuild() throws IOException {
10951102
// the following is new for opensearch: we write the distribution to support any "forks"

libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamOutput.java

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.opensearch.core.common.settings.SecureString;
5555
import org.opensearch.core.common.text.Text;
5656
import org.opensearch.core.concurrency.OpenSearchRejectedExecutionException;
57+
import org.opensearch.semver.SemverRange;
5758

5859
import java.io.EOFException;
5960
import java.io.FileNotFoundException;
@@ -784,6 +785,10 @@ public final void writeOptionalInstant(@Nullable Instant instant) throws IOExcep
784785
o.writeByte((byte) 26);
785786
o.writeString(v.toString());
786787
});
788+
writers.put(SemverRange.class, (o, v) -> {
789+
o.writeByte((byte) 27);
790+
o.writeSemverRange((SemverRange) v);
791+
});
787792
WRITERS = Collections.unmodifiableMap(writers);
788793
}
789794

@@ -1101,6 +1106,10 @@ public void writeVersion(final Version version) throws IOException {
11011106
writeVInt(version.id);
11021107
}
11031108

1109+
public void writeSemverRange(final SemverRange range) throws IOException {
1110+
writeString(range.toString());
1111+
}
1112+
11041113
/** Writes the OpenSearch {@link Build} informn to the output stream */
11051114
public void writeBuild(final Build build) throws IOException {
11061115
// the following is new for opensearch: we write the distribution name to support any "forks" of the code

0 commit comments

Comments
 (0)