|
5 | 5 | import com.atlassian.oai.validator.report.ValidationReport; |
6 | 6 | import com.getyourguide.openapi.validation.api.log.LogLevel; |
7 | 7 | import com.getyourguide.openapi.validation.api.model.ValidatorConfiguration; |
| 8 | +import com.getyourguide.openapi.validation.core.validator.MultipleSpecOpenApiInteractionValidatorWrapper; |
| 9 | +import com.getyourguide.openapi.validation.core.validator.OpenApiInteractionValidatorWrapper; |
| 10 | +import com.getyourguide.openapi.validation.core.validator.SingleSpecOpenApiInteractionValidatorWrapper; |
8 | 11 | import java.io.BufferedReader; |
9 | 12 | import java.io.File; |
10 | 13 | import java.io.IOException; |
11 | 14 | import java.io.InputStreamReader; |
12 | 15 | import java.nio.charset.StandardCharsets; |
13 | 16 | import java.util.Map; |
| 17 | +import java.util.Objects; |
14 | 18 | import java.util.Optional; |
15 | 19 | import java.util.stream.Collectors; |
16 | 20 | import javax.annotation.Nullable; |
17 | 21 | import lombok.NonNull; |
18 | 22 | import lombok.extern.slf4j.Slf4j; |
19 | 23 | import org.apache.commons.io.FileUtils; |
| 24 | +import org.apache.commons.lang3.tuple.Pair; |
20 | 25 |
|
21 | 26 | @Slf4j |
22 | 27 | public class OpenApiInteractionValidatorFactory { |
23 | 28 | @Nullable |
24 | | - public OpenApiInteractionValidator build(String specificationFilePath, ValidatorConfiguration configuration) { |
| 29 | + public OpenApiInteractionValidatorWrapper build( |
| 30 | + String specificationFilePath, |
| 31 | + ValidatorConfiguration configuration |
| 32 | + ) { |
| 33 | + if (configuration.getSpecificationPaths() != null && !configuration.getSpecificationPaths().isEmpty()) { |
| 34 | + return buildMultipleSpecOpenApiInteractionValidatorWrapper(configuration); |
| 35 | + } |
| 36 | + |
25 | 37 | var specOptional = loadOpenAPISpec(specificationFilePath); |
26 | 38 | if (specOptional.isEmpty()) { |
27 | 39 | log.info("OpenAPI spec file could not be found [validation disabled]"); |
28 | 40 | return null; |
29 | 41 | } |
30 | 42 |
|
31 | | - var spec = specOptional.get(); |
| 43 | + return buildSingleSpecOpenApiInteractionValidatorWrapper(specOptional.get(), |
| 44 | + configuration.getLevelResolverLevels(), configuration.getLevelResolverDefaultLevel()); |
| 45 | + } |
| 46 | + |
| 47 | + private MultipleSpecOpenApiInteractionValidatorWrapper buildMultipleSpecOpenApiInteractionValidatorWrapper( |
| 48 | + ValidatorConfiguration configuration) { |
| 49 | + var validators = configuration.getSpecificationPaths().stream() |
| 50 | + .map(entry -> { |
| 51 | + var path = entry.specificationFilePath(); |
| 52 | + var specOptional = loadSpecFromPath(path).or(() -> loadSpecFromResources(path)); |
| 53 | + if (specOptional.isEmpty()) { |
| 54 | + log.error("OpenAPI spec file {} could not be found", path); |
| 55 | + return null; |
| 56 | + } |
| 57 | + var validator = buildSingleSpecOpenApiInteractionValidatorWrapper(specOptional.get(), |
| 58 | + configuration.getLevelResolverLevels(), configuration.getLevelResolverDefaultLevel()); |
| 59 | + return Pair.of(entry.pathPattern(), (OpenApiInteractionValidatorWrapper) validator); |
| 60 | + }) |
| 61 | + .filter(Objects::nonNull) |
| 62 | + .collect(Collectors.toList()); |
| 63 | + return new MultipleSpecOpenApiInteractionValidatorWrapper(validators); |
| 64 | + } |
| 65 | + |
| 66 | + private SingleSpecOpenApiInteractionValidatorWrapper buildSingleSpecOpenApiInteractionValidatorWrapper( |
| 67 | + String spec, |
| 68 | + Map<String, LogLevel> levelResolverLevels, |
| 69 | + LogLevel levelResolverDefaultLevel |
| 70 | + ) { |
32 | 71 | try { |
33 | | - return OpenApiInteractionValidator |
| 72 | + var validator = OpenApiInteractionValidator |
34 | 73 | .createForInlineApiSpecification(spec) |
35 | 74 | .withResolveRefs(true) |
36 | 75 | .withResolveCombinators(true) // Inline to avoid problems with allOf |
37 | | - .withLevelResolver(buildLevelResolver(configuration)) |
| 76 | + .withLevelResolver(buildLevelResolver(levelResolverLevels, levelResolverDefaultLevel)) |
38 | 77 | .build(); |
| 78 | + return new SingleSpecOpenApiInteractionValidatorWrapper(validator); |
39 | 79 | } catch (Throwable e) { |
40 | 80 | log.error("Could not initialize OpenApiInteractionValidator [validation disabled]", e); |
41 | 81 | return null; |
@@ -95,17 +135,22 @@ private Optional<String> loadSpecFromResources(String resourceFileLocation) { |
95 | 135 | } |
96 | 136 | } |
97 | 137 |
|
98 | | - private LevelResolver buildLevelResolver(ValidatorConfiguration configuration) { |
| 138 | + private LevelResolver buildLevelResolver( |
| 139 | + Map<String, LogLevel> levelResolverLevels, |
| 140 | + LogLevel levelResolverDefaultLevel |
| 141 | + ) { |
99 | 142 | var builder = LevelResolver.create(); |
100 | | - if (configuration.getLevelResolverLevels() != null && !configuration.getLevelResolverLevels().isEmpty()) { |
| 143 | + if (levelResolverLevels != null && !levelResolverLevels.isEmpty()) { |
101 | 144 | builder.withLevels( |
102 | | - configuration.getLevelResolverLevels().entrySet().stream() |
103 | | - .collect(Collectors.toMap(Map.Entry::getKey, entry -> mapLevel(entry.getValue()).orElse(ValidationReport.Level.INFO))) |
| 145 | + levelResolverLevels.entrySet().stream() |
| 146 | + .collect(Collectors.toMap(Map.Entry::getKey, entry -> |
| 147 | + mapLevel(entry.getValue()).orElse(ValidationReport.Level.INFO)) |
| 148 | + ) |
104 | 149 | ); |
105 | 150 | } |
106 | 151 | return builder |
107 | 152 | // this will cause all messages to be warn by default |
108 | | - .withDefaultLevel(mapLevel(configuration.getLevelResolverDefaultLevel()).orElse(ValidationReport.Level.INFO)) |
| 153 | + .withDefaultLevel(mapLevel(levelResolverDefaultLevel).orElse(ValidationReport.Level.INFO)) |
109 | 154 | .build(); |
110 | 155 | } |
111 | 156 |
|
|
0 commit comments