1 package de.dlr.shepard.common.filters;
2
3 import io.quarkus.smallrye.openapi.OpenApiFilter;
4 import java.util.LinkedHashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.stream.Collectors;
8 import org.eclipse.microprofile.openapi.OASFactory;
9 import org.eclipse.microprofile.openapi.OASFilter;
10 import org.eclipse.microprofile.openapi.models.OpenAPI;
11 import org.eclipse.microprofile.openapi.models.PathItem;
12 import org.eclipse.microprofile.openapi.models.Paths;
13 import org.eclipse.microprofile.openapi.models.media.Schema;
14
15 @OpenApiFilter(OpenApiFilter.RunStage.BUILD)
16 public class ApiPathFilter implements OASFilter {
17
18 @Override
19 public void filterOpenAPI(OpenAPI openAPI) {
20 fixOpenApiPaths(openAPI);
21 excludeExtraHealthEndpointsAndAdjustHealthzTag(openAPI);
22 sortPropertiesOfHealthCheckSchemas(openAPI);
23 }
24
25
26
27
28
29
30
31
32 private void fixOpenApiPaths(OpenAPI openAPI) {
33 Paths newPaths = OASFactory.createPaths();
34
35 Map<String, PathItem> paths = openAPI.getPaths().getPathItems();
36 for (var entry : paths.entrySet()) {
37
38 String modifiedPath = entry.getKey().replace("/shepard/api", "");
39 newPaths.addPathItem(modifiedPath, entry.getValue());
40 }
41 openAPI.setPaths(newPaths);
42 }
43
44
45
46
47 private void excludeExtraHealthEndpointsAndAdjustHealthzTag(OpenAPI openAPI) {
48 Paths newPaths = OASFactory.createPaths();
49
50 Map<String, PathItem> paths = openAPI.getPaths().getPathItems();
51
52 newPaths.setPathItems(
53 paths
54 .entrySet()
55 .stream()
56 .filter(path -> !List.of("/healthz/ready", "/healthz/live", "/healthz/started").contains(path.getKey()))
57 .map(path -> {
58 if (
59 path.getValue().getGET() == null || !path.getValue().getGET().getTags().contains("MicroProfile Health")
60 ) return path;
61
62 PathItem newPathItem = path.getValue();
63 newPathItem.getGET().setTags(List.of("healthz"));
64 newPathItem.getGET().setOperationId("getServerHealth");
65 return Map.entry(path.getKey(), newPathItem);
66 })
67 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
68 );
69 openAPI.setPaths(newPaths);
70 }
71
72 private void sortPropertiesOfHealthCheckSchemas(OpenAPI openAPI) {
73 Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
74
75 openAPI
76 .getComponents()
77 .setSchemas(
78 schemas
79 .entrySet()
80 .stream()
81 .map(schema -> {
82 if (!List.of("HealthCheck", "HealthResponse").contains(schema.getKey())) {
83 return schema;
84 }
85
86 schema
87 .getValue()
88 .setProperties(
89 schema
90 .getValue()
91 .getProperties()
92 .entrySet()
93 .stream()
94 .sorted(Map.Entry.comparingByKey())
95 .collect(
96 Collectors.toMap(
97 Map.Entry::getKey,
98 Map.Entry::getValue,
99 (oldValue, newValue) -> oldValue,
100 LinkedHashMap::new
101 )
102 )
103 );
104 return schema;
105 })
106 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
107 );
108 }
109 }