Skip to content

Commit 617b302

Browse files
committed
Registry client option to set a low boundary for recommended streams on
the client side
1 parent 23c625b commit 617b302

File tree

13 files changed

+520
-39
lines changed

13 files changed

+520
-39
lines changed

docs/src/main/asciidoc/extension-registry-user.adoc

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,55 @@ Applications using a registry client can be configured using environment variabl
221221

222222
`QUARKUS_REGISTRIES` environment variable can be used to specify which registries should be enabled as a comma-separated list of registry IDs.
223223
For example
224-
```
224+
----
225225
QUARKUS_REGISTRIES=registry.acme.org,registry.quarkus.io
226-
```
226+
----
227227
That alone will be enough to initialize a registry client to pull extension catalogs from two registries using their default configurations.
228228

229229
Certain registry options could be initialized with their specific environment variables. Each such option will have the following environment variable prefix:
230-
```
230+
----
231231
QUARKUS_REGISTRY_<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>_
232-
```
232+
----
233233
where `<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>` is a registry ID with each character converted to uppercase and a `.` replaced with `_`. For example, `REGISTRY_ACME_ORG`.
234234

235-
The following options can be configured with this approach:
235+
Below are examples of various options that can be configured following this approach.
236236

237-
- Repository URL, for example `QUARKUS_REGISTRY_REGISTRY_ACME_ORG_REPO_URL=https://internal.registry.acme.org/maven`
238-
- Update policy, for example `QUARKUS_REGISTRY_REGISTRY_ACME_ORG_UPDATE_POLICY=always`
239-
- Offering, for example `QUARKUS_REGISTRY_REGISTRY_ACME_ORG_OFFERING=acme-magic`
237+
===== Repository URL
238+
239+
`QUARKUS_REGISTRY_<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>_REPO_URL=<REPO_URL>`
240+
241+
Example:
242+
----
243+
QUARKUS_REGISTRY_REGISTRY_ACME_ORG_REPO_URL=https://internal.registry.acme.org/maven
244+
----
245+
246+
===== Update policy
247+
248+
`QUARKUS_REGISTRY_<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>_UPDATE_POLICY=<UPDATE_POLICY>`
249+
250+
Example:
251+
----
252+
QUARKUS_REGISTRY_REGISTRY_ACME_ORG_UPDATE_POLICY=always
253+
----
254+
255+
===== Offering
256+
257+
`QUARKUS_REGISTRY_<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>_OFFERING=<OFFERING>`
258+
259+
Example:
260+
----
261+
QUARKUS_REGISTRY_REGISTRY_ACME_ORG_OFFERING=acme-magic
262+
----
263+
264+
===== Recommend Streams From
265+
266+
Set the oldest acceptable stream value per platform. Streams older than the configured values will be ignored by the client.
267+
268+
`QUARKUS_REGISTRY_<UPPERCASED_AND_UNDERSCORED_REGISTRY_ID>_RECOMMEND_STREAMS_FROM_<UPPERCASED_AND_UNDERSCORED_PLATFORM_KEY>=<STREAM_ID>`
269+
270+
Where `UPPERCASED_AND_UNDERSCORED_PLATFORM_KEY` is a platform key with each character converted to uppercase and a `.` replaced with `_`. For example, `IO_QUARKUS_PLATFORM`.
271+
272+
Example:
273+
----
274+
QUARKUS_REGISTRY_REGISTRY_ACME_ORG_RECOMMEND_STREAMS_FROM_IO_QUARKUS_PLATFORM=3.27
275+
----

independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,15 @@ private static class ProjectDependencyInfo {
9999
// necessary to set the versions from the selected origins
100100
this.dataCatalog = CatalogMergeUtility.merge(extensionOrigins);
101101
// collect platform BOMs to import
102-
boolean sawFirstPlatform = false;
103102
ExtensionCatalog primaryCatalog = null;
104103
this.platformBoms = new ArrayList<>(extensionOrigins.size());
105104
for (ExtensionCatalog c : extensionOrigins) {
106105
if (c.isPlatform()) {
107-
if (c.getBom().getArtifactId().equals(QUARKUS_BOM) || !sawFirstPlatform) {
106+
// use either the first platform catalog or the first quarkus-bom catalog, if found
107+
if (primaryCatalog == null
108+
|| !primaryCatalog.getBom().getArtifactId().equals(QUARKUS_BOM)
109+
&& c.getBom().getArtifactId().equals(QUARKUS_BOM)) {
108110
primaryCatalog = c;
109-
sawFirstPlatform = true;
110111
}
111112
platformBoms.add(c.getBom());
112113
}

independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/registry/client/TestRegistryClientBuilder.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.quarkus.devtools.testing.registry.client;
22

3+
import static io.quarkus.registry.Constants.OFFERING;
4+
import static io.quarkus.registry.Constants.RECOMMEND_STREAMS_FROM;
5+
36
import java.io.BufferedWriter;
47
import java.io.IOException;
58
import java.io.UncheckedIOException;
@@ -390,12 +393,26 @@ public TestRegistryBuilder recognizedQuarkusVersions(String expr, boolean exclus
390393
}
391394

392395
public TestRegistryBuilder setOffering(String offering) {
396+
return setExtraOption(OFFERING, offering);
397+
}
398+
399+
public TestRegistryBuilder setRecommendStreamsFrom(String platformKey, String streamId) {
400+
Map<String, String> recommendStreamsFrom = (Map<String, String>) config.getExtra().get(RECOMMEND_STREAMS_FROM);
401+
if (recommendStreamsFrom == null) {
402+
recommendStreamsFrom = new HashMap<>(2);
403+
setExtraOption(RECOMMEND_STREAMS_FROM, recommendStreamsFrom);
404+
}
405+
recommendStreamsFrom.put(platformKey, streamId);
406+
return this;
407+
}
408+
409+
private TestRegistryBuilder setExtraOption(String name, Object value) {
393410
var extra = config.getExtra();
394411
if (extra == null || extra.isEmpty()) {
395-
extra = new HashMap<>(1);
412+
extra = new HashMap<>(4);
396413
config.setExtra(extra);
397414
}
398-
extra.put(Constants.OFFERING, offering);
415+
extra.put(name, value);
399416
return this;
400417
}
401418

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.quarkus.devtools.project.create;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.quarkus.maven.dependency.ArtifactCoords;
10+
11+
/**
12+
* This test does not configure the recommend-streams-from but tests the default setup
13+
*/
14+
public class RecommendStreamsFromScenario1Test extends RecommendStreamsFromScenarioBase {
15+
16+
@Test
17+
public void createOfferingA() throws Exception {
18+
final Path projectDir = newProjectDir(getClass().getSimpleName());
19+
createProject(projectDir, List.of("ext-a", "ext-b"));
20+
21+
assertModel(projectDir,
22+
List.of(mainPlatformBom(),
23+
platformMemberBomCoords("acme-a-bom"),
24+
platformMemberBomCoords("acme-b-bom")),
25+
List.of(ArtifactCoords.jar("io.acme", "ext-a", null),
26+
ArtifactCoords.jar("io.acme", "ext-b", null)),
27+
Map.of("quarkus.platform.group-id", DOWNSTREAM_PLATFORM_KEY,
28+
"quarkus.platform.artifact-id", "quarkus-bom",
29+
"quarkus.platform.version", "2.2.2.downstream"));
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.quarkus.devtools.project.create;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder;
10+
import io.quarkus.maven.dependency.ArtifactCoords;
11+
12+
/**
13+
* This test does not configure the recommend-streams-from but configures an offering, which makes the tools give preference to
14+
* an older stream
15+
*/
16+
public class RecommendStreamsFromScenario2Test extends RecommendStreamsFromScenarioBase {
17+
18+
@Override
19+
protected void setDownstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
20+
registry.setOffering("offering-a");
21+
}
22+
23+
@Test
24+
public void createOfferingA() throws Exception {
25+
final Path projectDir = newProjectDir(getClass().getSimpleName());
26+
createProject(projectDir, List.of("ext-a", "ext-b"));
27+
28+
assertModel(projectDir,
29+
List.of(mainPlatformBom(),
30+
platformMemberBomCoords("acme-a-bom"),
31+
platformMemberBomCoords("acme-b-bom")),
32+
List.of(ArtifactCoords.jar("io.acme", "ext-a", null),
33+
ArtifactCoords.jar("io.acme", "ext-b", null)),
34+
Map.of("quarkus.platform.group-id", DOWNSTREAM_PLATFORM_KEY,
35+
"quarkus.platform.artifact-id", "quarkus-bom",
36+
"quarkus.platform.version", "1.1.1.downstream"));
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.quarkus.devtools.project.create;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder;
10+
import io.quarkus.maven.dependency.ArtifactCoords;
11+
12+
public class RecommendStreamsFromScenario3Test extends RecommendStreamsFromScenarioBase {
13+
14+
@Override
15+
protected void setDownstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
16+
registry.setOffering("offering-a")
17+
.setRecommendStreamsFrom(DOWNSTREAM_PLATFORM_KEY, "2.2");
18+
}
19+
20+
@Test
21+
public void createOfferingA() throws Exception {
22+
final Path projectDir = newProjectDir(getClass().getSimpleName());
23+
createProject(projectDir, List.of("ext-a", "ext-b"));
24+
25+
assertModel(projectDir,
26+
List.of(mainPlatformBom(),
27+
platformMemberBomCoords("acme-a-bom"),
28+
ArtifactCoords.pom(UPSTREAM_PLATFORM_KEY, "acme-b-bom", "2.2.2")),
29+
List.of(ArtifactCoords.jar("io.acme", "ext-a", null),
30+
ArtifactCoords.jar("io.acme", "ext-b", null)),
31+
Map.of("quarkus.platform.group-id", DOWNSTREAM_PLATFORM_KEY,
32+
"quarkus.platform.artifact-id", "quarkus-bom",
33+
"quarkus.platform.version", "2.2.2.downstream"));
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.quarkus.devtools.project.create;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder;
10+
import io.quarkus.maven.dependency.ArtifactCoords;
11+
12+
public class RecommendStreamsFromScenario4Test extends RecommendStreamsFromScenarioBase {
13+
14+
@Override
15+
protected void setDownstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
16+
registry.setOffering("offering-a")
17+
.setRecommendStreamsFrom(DOWNSTREAM_PLATFORM_KEY, "2.2");
18+
}
19+
20+
@Override
21+
protected void setUpstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
22+
registry.setRecommendStreamsFrom(UPSTREAM_PLATFORM_KEY, "3.3");
23+
}
24+
25+
@Test
26+
public void createOfferingA() throws Exception {
27+
final Path projectDir = newProjectDir(getClass().getSimpleName());
28+
createProject(projectDir, List.of("ext-a", "ext-b"));
29+
30+
assertModel(projectDir,
31+
List.of(mainPlatformBom(),
32+
platformMemberBomCoords("acme-a-bom"),
33+
platformMemberBomCoords("acme-b-bom")),
34+
List.of(ArtifactCoords.jar("io.acme", "ext-a", null),
35+
ArtifactCoords.jar("io.acme", "ext-b", null)),
36+
Map.of("quarkus.platform.group-id", UPSTREAM_PLATFORM_KEY,
37+
"quarkus.platform.artifact-id", "quarkus-bom",
38+
"quarkus.platform.version", "3.3.3"));
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package io.quarkus.devtools.project.create;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import org.junit.jupiter.api.BeforeEach;
7+
8+
import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder;
9+
10+
public class RecommendStreamsFromScenarioBase extends MultiplePlatformBomsTestBase {
11+
protected static final String UPSTREAM_PLATFORM_KEY = "io.upstream.platform";
12+
protected static final String DOWNSTREAM_PLATFORM_KEY = "io.downstream.platform";
13+
14+
@BeforeEach
15+
public void setup() throws Exception {
16+
TestRegistryClientBuilder registryClientBuilder = TestRegistryClientBuilder.newInstance()
17+
//.debug()
18+
.baseDir(configDir());
19+
20+
var downstreamRegistry = registryClientBuilder
21+
// registry
22+
.newRegistry("downstream.registry.test")
23+
.recognizedQuarkusVersions("*downstream");
24+
setDownstreamRegistryExtraOptions(downstreamRegistry);
25+
26+
downstreamRegistry
27+
// platform key
28+
.newPlatform(DOWNSTREAM_PLATFORM_KEY)
29+
.newStream("2.2")
30+
// 2.2.2 release
31+
.newRelease("2.2.2.downstream")
32+
.quarkusVersion("2.2.2.downstream")
33+
.upstreamQuarkusVersion("2.2.2")
34+
// default bom including quarkus-core + essential metadata
35+
.addCoreMember().release()
36+
// platform member
37+
.newMember("acme-a-bom")
38+
.addExtensionWithMetadata("io.acme", "ext-a", "2.2.2.downstream",
39+
Map.of("offering-a-support", List.of("supported")))
40+
.release()
41+
.newMember("acme-b-bom")
42+
.addExtensionWithMetadata("io.acme", "ext-b", "2.2.2.downstream",
43+
Map.of("offering-b-support", List.of("supported")))
44+
.release().stream().platform()
45+
.newStream("1.1")
46+
// 1.1.1 release
47+
.newRelease("1.1.1.downstream")
48+
.quarkusVersion("1.1.1.downstream")
49+
.upstreamQuarkusVersion("1.1.1")
50+
// default bom including quarkus-core + essential metadata
51+
.addCoreMember().release()
52+
// platform member
53+
.newMember("acme-a-bom")
54+
.addExtensionWithMetadata("io.acme", "ext-a", "1.1.1.downstream",
55+
Map.of("offering-a-support", List.of("supported")))
56+
.release()
57+
.newMember("acme-b-bom")
58+
.addExtensionWithMetadata("io.acme", "ext-b", "1.1.1.downstream",
59+
// on purpose included in offering-a
60+
Map.of("offering-a-support", List.of("supported")));
61+
62+
var upstreamRegistry = registryClientBuilder.newRegistry("upstream.registry.test");
63+
setUpstreamRegistryExtraOptions(upstreamRegistry);
64+
65+
upstreamRegistry
66+
// platform key
67+
.newPlatform(UPSTREAM_PLATFORM_KEY)
68+
// 3.3 STREAM
69+
.newStream("3.3")
70+
// 3.3.3 release
71+
.newRelease("3.3.3")
72+
.quarkusVersion("3.3.3")
73+
// default bom including quarkus-core + essential metadata
74+
.addCoreMember().release()
75+
.newMember("acme-a-bom").addExtension("io.acme", "ext-a", "3.3.3").release()
76+
.newMember("acme-b-bom").addExtension("io.acme", "ext-b", "3.3.3").release()
77+
.stream().platform()
78+
// 2.2 STREAM
79+
.newStream("2.2")
80+
// 2.2.2 release
81+
.newRelease("2.2.2")
82+
.quarkusVersion("2.2.2")
83+
// default bom including quarkus-core + essential metadata
84+
.addCoreMember().release()
85+
.newMember("acme-a-bom").addExtension("io.acme", "ext-a", "2.2.2").release()
86+
.newMember("acme-b-bom").addExtension("io.acme", "ext-b", "2.2.2").release()
87+
.stream().platform()
88+
// 1.1 STREAM
89+
.newStream("1.1")
90+
// 1.1.1 release
91+
.newRelease("1.1.1")
92+
.quarkusVersion("1.1.1")
93+
// default bom including quarkus-core + essential metadata
94+
.addCoreMember().release()
95+
.newMember("acme-a-bom").addExtension("io.acme", "ext-a", "1.1.1").release()
96+
.newMember("acme-b-bom").addExtension("io.acme", "ext-b", "1.1.1");
97+
98+
registryClientBuilder.build();
99+
enableRegistryClient();
100+
}
101+
102+
protected void setDownstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
103+
}
104+
105+
protected void setUpstreamRegistryExtraOptions(TestRegistryClientBuilder.TestRegistryBuilder registry) {
106+
}
107+
108+
protected String getMainPlatformKey() {
109+
return DOWNSTREAM_PLATFORM_KEY;
110+
}
111+
}

independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/Constants.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ public interface Constants {
2222
String LAST_UPDATED = "last-updated";
2323

2424
/**
25-
* Registry configuration option allowing users to limit the extension catalog from a registry to a specific offering
25+
* Registry client configuration option allowing users to limit the extension catalog from a registry to a specific offering
2626
*/
2727
String OFFERING = "offering";
2828

29+
/**
30+
* Registry client configuration option allowing users to set a low boundary for the recommended streams per platform
31+
*/
32+
String RECOMMEND_STREAMS_FROM = "recommend-streams-from";
33+
2934
/**
3035
* An internal key optionally added to extension metadata by a registry client
3136
* to indicate a user configured offering-based support key that should be displayed by extension listing commands

0 commit comments

Comments
 (0)