Skip to content

Commit 5b664b0

Browse files
authored
Merge pull request #169 from Karm/issue-163
Adds /supportMatrix and /supportMatrix/servers resources to REST API
2 parents 21eae5e + 0b8eece commit 5b664b0

File tree

3 files changed

+216
-14
lines changed

3 files changed

+216
-14
lines changed

src/main/java/org/eclipse/microprofile/starter/rest/APIEndpointLatest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,27 @@ public Response listMPVersions() {
6262
return api.listMPVersions();
6363
}
6464

65+
@Path("/supportMatrix")
66+
@GET
67+
@Produces({"application/json"})
68+
public Response supportMatrix(@HeaderParam(HttpHeaders.IF_NONE_MATCH) String ifNoneMatch) {
69+
return api.supportMatrix(ifNoneMatch);
70+
}
71+
72+
@Path("/supportMatrix/servers")
73+
@GET
74+
@Produces({"application/json"})
75+
public Response supportMatrixServers(@HeaderParam(HttpHeaders.IF_NONE_MATCH) String ifNoneMatch) {
76+
return api.supportMatrixServers(ifNoneMatch);
77+
}
78+
6579
@Path("/mpVersion/{mpVersion}")
6680
@GET
6781
@Produces({"application/json"})
6882
public Response listOptions(@NotNull @PathParam("mpVersion") MicroProfileVersion mpVersion) {
6983
return api.listOptions(mpVersion);
7084
}
7185

72-
7386
@Path("/project")
7487
@GET
7588
@Produces({"application/zip", "application/json"})

src/main/java/org/eclipse/microprofile/starter/rest/APIService.java

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
import javax.ws.rs.core.EntityTag;
4949
import javax.ws.rs.core.MediaType;
5050
import javax.ws.rs.core.Response;
51+
import java.util.ArrayList;
52+
import java.util.Collections;
5153
import java.util.HashMap;
54+
import java.util.LinkedHashMap;
5255
import java.util.List;
5356
import java.util.Map;
5457
import java.util.Scanner;
@@ -66,6 +69,10 @@ public class APIService {
6669
private static final Logger LOG = Logger.getLogger(APIService.class.getName());
6770

6871
private Map<MicroProfileVersion, MPOptionsAvailable> mpvToOptions;
72+
private EntityTag mpvToOptionsEtag;
73+
74+
private Map<SupportedServer, Map<MicroProfileVersion, List<MicroprofileSpec>>> serversToOptions;
75+
private EntityTag serversToOptionsEtag;
6976

7077
private String readme;
7178
private EntityTag readmeEtag;
@@ -78,18 +85,26 @@ public class APIService {
7885

7986
@PostConstruct
8087
public void init() {
81-
mpvToOptions =
82-
new HashMap<MicroProfileVersion, MPOptionsAvailable>(MicroProfileVersion.values().length) {
83-
{
84-
Stream.of(MicroProfileVersion.values()).forEach(mpv -> put(mpv, new MPOptionsAvailable(
85-
Stream.of(SupportedServer.values())
86-
.filter(v -> v.getMpVersions().contains(mpv)).collect(Collectors.toList()),
87-
Stream.of(MicroprofileSpec.values())
88-
.filter(v -> v.getMpVersions().contains(mpv)).collect(Collectors.toList()))));
89-
90-
}
91-
92-
};
88+
// Keys are MP versions and values are servers and specs
89+
mpvToOptions = new HashMap<>(MicroProfileVersion.values().length);
90+
Stream.of(MicroProfileVersion.values()).filter(mpv -> mpv != MicroProfileVersion.NONE).forEach(mpv -> {
91+
List<SupportedServer> supportedServers = Stream.of(SupportedServer.values())
92+
.filter(v -> v.getMpVersions().contains(mpv)).collect(Collectors.toList());
93+
List<MicroprofileSpec> specs = Stream.of(MicroprofileSpec.values())
94+
.filter(v -> v.getMpVersions().contains(mpv)).collect(Collectors.toList());
95+
mpvToOptions.put(mpv, new MPOptionsAvailable(supportedServers, specs));
96+
});
97+
mpvToOptionsEtag = new EntityTag(Integer.toHexString(31 * version.getGit().hashCode() + mpvToOptions.hashCode()));
98+
// Keys are servers and values are MP versions and specs
99+
serversToOptions = new HashMap<>(SupportedServer.values().length);
100+
for (SupportedServer s : SupportedServer.values()) {
101+
Map<MicroProfileVersion, List<MicroprofileSpec>> mpvToSpec = new HashMap<>(s.getMpVersions().size());
102+
s.getMpVersions().forEach(mpv -> mpvToSpec.put(
103+
mpv,
104+
Stream.of(MicroprofileSpec.values()).filter(v -> v.getMpVersions().contains(mpv)).collect(Collectors.toList())));
105+
serversToOptions.put(s, mpvToSpec);
106+
}
107+
serversToOptionsEtag = new EntityTag(Integer.toHexString(31 * version.getGit().hashCode() + serversToOptions.hashCode()));
93108
try (Scanner s = new Scanner(FilesLocator.class.getClassLoader()
94109
.getResourceAsStream("/REST-README.md")).useDelimiter("\\A")) {
95110
readme = (s.hasNext() ? s.next() : "") + "\n" + version.getGit() + "\n";
@@ -130,7 +145,7 @@ public Response readme(String ifNoneMatch) {
130145
return Response.notModified().build();
131146
}
132147
}
133-
return Response.ok(readme).build();
148+
return Response.ok(readme).tag(readmeEtag).build();
134149
}
135150

136151
public Response listMPVersions() {
@@ -142,6 +157,30 @@ public Response listMPVersions() {
142157
).build();
143158
}
144159

160+
public Response supportMatrix(String ifNoneMatch) {
161+
if (ifNoneMatch != null) {
162+
if (mpvToOptionsEtag.toString().equals(ifNoneMatch)) {
163+
return Response.notModified().build();
164+
}
165+
}
166+
return Response.ok(mpvToOptions, MediaType.APPLICATION_JSON_TYPE).tag(mpvToOptionsEtag).build();
167+
}
168+
169+
public Response supportMatrixServers(String ifNoneMatch) {
170+
if (ifNoneMatch != null) {
171+
if (serversToOptionsEtag.toString().equals(ifNoneMatch)) {
172+
return Response.notModified().build();
173+
}
174+
}
175+
List<SupportedServer> servers = new ArrayList<>(serversToOptions.keySet());
176+
Collections.shuffle(servers);
177+
Map<SupportedServer, Map<MicroProfileVersion, List<MicroprofileSpec>>> rndServersToOptions = new LinkedHashMap<>(servers.size());
178+
for (SupportedServer s : servers) {
179+
rndServersToOptions.put(s, serversToOptions.get(s));
180+
}
181+
return Response.ok(rndServersToOptions, MediaType.APPLICATION_JSON_TYPE).tag(serversToOptionsEtag).build();
182+
}
183+
145184
public Response listOptions(MicroProfileVersion mpVersion) {
146185
return Response.ok(mpvToOptions.get(mpVersion)).build();
147186
}

src/main/resources/REST-README.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,153 @@ PS C:\> $headers = @{
244244
>> }
245245
PS C:\> Invoke-WebRequest -InFile ./all.json -OutFile project.zip -Method Post -Uri "https://start.microprofile.io/api/1/project" -Headers $headers
246246
```
247+
248+
# Integration with IDEs
249+
250+
If it is preferred to acquire all valid options in a one request the ```supportMatrix``` call is recommended.
251+
The integration code [SHOULD](https://tools.ietf.org/html/rfc2119) use [Etag](https://tools.ietf.org/html/rfc7232#section-2.3) response header
252+
and [If-None-Match](https://tools.ietf.org/html/rfc7232#section-3.2) request header so as to avoid unnecessary deserialization of identical responses.
253+
254+
## MicroProfile versions as keys
255+
256+
```
257+
$ curl -i https://start.microprofile.io/api/1/supportMatrix
258+
...
259+
ETag: "44730639"
260+
...
261+
{
262+
"MP12": {
263+
"supportedServers": [
264+
"WILDFLY_SWARM",
265+
"PAYARA_MICRO",
266+
"THORNTAIL_V2",
267+
"TOMEE",
268+
"LIBERTY",
269+
"KUMULUZEE",
270+
"HELIDON"
271+
],
272+
"specs": [
273+
"CONFIG",
274+
"FAULT_TOLERANCE",
275+
"JWT_AUTH",
276+
"METRICS",
277+
"HEALTH_CHECKS"
278+
]
279+
},
280+
"MP21": {
281+
"supportedServers": [
282+
"KUMULUZEE",
283+
"THORNTAIL_V2",
284+
"LIBERTY",
285+
"PAYARA_MICRO"
286+
],
287+
"specs": [
288+
"CONFIG",
289+
"FAULT_TOLERANCE",
290+
"JWT_AUTH",
291+
"METRICS",
292+
"HEALTH_CHECKS",
293+
"OPEN_API",
294+
"OPEN_TRACING",
295+
"REST_CLIENT"
296+
]
297+
},
298+
...removed for brevity...
299+
}
300+
```
301+
302+
Using value from ETag in If-None-Match:
303+
304+
```
305+
$ curl '-HIf-None-Match: "44730639"' -i https://start.microprofile.io/api/1/supportMatrix
306+
...
307+
HTTP/1.1 304 Not Modified
308+
```
309+
310+
## Server implementations as keys
311+
312+
```
313+
$ curl -i https://start.microprofile.io/api/1/supportMatrix/servers
314+
...
315+
ETag: "7b99230f"
316+
...
317+
{
318+
"HELIDON": {
319+
"MP12": [
320+
"CONFIG",
321+
"FAULT_TOLERANCE",
322+
"JWT_AUTH",
323+
"METRICS",
324+
"HEALTH_CHECKS"
325+
]
326+
},
327+
"PAYARA_MICRO": {
328+
"MP20": [
329+
"CONFIG",
330+
"FAULT_TOLERANCE",
331+
"JWT_AUTH",
332+
"METRICS",
333+
"HEALTH_CHECKS",
334+
"OPEN_API",
335+
"OPEN_TRACING",
336+
"REST_CLIENT"
337+
],
338+
"MP13": [
339+
"CONFIG",
340+
"FAULT_TOLERANCE",
341+
"JWT_AUTH",
342+
"METRICS",
343+
"HEALTH_CHECKS",
344+
"OPEN_API",
345+
"OPEN_TRACING",
346+
"REST_CLIENT"
347+
],
348+
"MP22": [
349+
"CONFIG",
350+
"FAULT_TOLERANCE",
351+
"JWT_AUTH",
352+
"METRICS",
353+
"HEALTH_CHECKS",
354+
"OPEN_API",
355+
"OPEN_TRACING",
356+
"REST_CLIENT"
357+
],
358+
"MP12": [
359+
"CONFIG",
360+
"FAULT_TOLERANCE",
361+
"JWT_AUTH",
362+
"METRICS",
363+
"HEALTH_CHECKS"
364+
],
365+
"MP14": [
366+
"CONFIG",
367+
"FAULT_TOLERANCE",
368+
"JWT_AUTH",
369+
"METRICS",
370+
"HEALTH_CHECKS",
371+
"OPEN_API",
372+
"OPEN_TRACING",
373+
"REST_CLIENT"
374+
],
375+
"MP21": [
376+
"CONFIG",
377+
"FAULT_TOLERANCE",
378+
"JWT_AUTH",
379+
"METRICS",
380+
"HEALTH_CHECKS",
381+
"OPEN_API",
382+
"OPEN_TRACING",
383+
"REST_CLIENT"
384+
]
385+
}
386+
...removed for brevity...
387+
}
388+
```
389+
390+
Using value from ETag in If-None-Match:
391+
392+
```
393+
$ curl '-HIf-None-Match: "7b99230f"' -i https://start.microprofile.io/api/1/supportMatrix/servers
394+
...
395+
HTTP/1.1 304 Not Modified
396+
```

0 commit comments

Comments
 (0)