Init commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
package com.krusoe.openapimerge.merge;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.v3.core.util.Json;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.PathItem;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.openapitools.codegen.validation.Invalid;
|
||||
import org.openapitools.codegen.validation.ValidationRule;
|
||||
import org.openapitools.codegen.validations.oas.OpenApiEvaluator;
|
||||
import org.openapitools.codegen.validations.oas.RuleConfiguration;
|
||||
import org.springframework.shell.command.annotation.Command;
|
||||
import org.springframework.shell.command.annotation.Option;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Command
|
||||
public class MergeCommand {
|
||||
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Command(description = "Merge APIs")
|
||||
public void merge(@Option(required = true, shortNames = {'d'}, longNames = {"dir"}) String dir, @Option(required = false, shortNames = {'o'}, longNames = {"out"}) String out) throws IOException {
|
||||
File dirFile = new File(dir);
|
||||
|
||||
if (FileUtils.isDirectory(dirFile)) {
|
||||
ApiSpec mergedSpec = new ApiSpec();
|
||||
for (File processedFile : FileUtils.listFiles(dirFile, new String[]{".json"}, true)) {
|
||||
System.out.println("Processing file: " + processedFile.getAbsolutePath());
|
||||
|
||||
ApiSpec currentFileSpec = objectMapper.readerFor(ApiSpec.class).readValue(processedFile);
|
||||
|
||||
mergedSpec.merge(currentFileSpec);
|
||||
}
|
||||
|
||||
var outFile = new File(dirFile, "mergedapi.json");
|
||||
if (outFile.exists()) {
|
||||
outFile.delete();
|
||||
}
|
||||
System.out.println("Writing merged APIs");
|
||||
try (OutputStream outStream = FileUtils.newOutputStream(outFile, false)) {
|
||||
objectMapper.writerWithDefaultPrettyPrinter().writeValue(outStream, mergedSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(description = "Validate APIs")
|
||||
public void validate(@Option(required = true, shortNames = {'f'}, longNames = {"file"}) String fileToBalidate) throws IOException {
|
||||
File outFile = new File(fileToBalidate);
|
||||
|
||||
if (outFile.isDirectory()) {
|
||||
System.out.println("Given file is an directory");
|
||||
} else {
|
||||
validateFile(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateFile(File outFile) throws IOException {
|
||||
if (outFile.exists()) {
|
||||
System.out.println("Validating OpenAPI file " + outFile.getAbsolutePath());
|
||||
OpenApiEvaluator evaluator = new OpenApiEvaluator(new RuleConfiguration());
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
OpenAPI validatedApi = Json.mapper().readValue(outFile, OpenAPI.class);
|
||||
|
||||
|
||||
var validationResult = evaluator.validate(validatedApi);
|
||||
|
||||
Set<String> uniqueOperationIds = new HashSet<>();
|
||||
Set<String> nonUniqueOperationIds = new HashSet<>();
|
||||
|
||||
|
||||
|
||||
|
||||
for (PathItem processedItem : validatedApi.getPaths().sequencedValues()) {
|
||||
Stream.of(processedItem.getDelete(),
|
||||
processedItem.getGet(),
|
||||
processedItem.getPost(),
|
||||
processedItem.getPut(),
|
||||
processedItem.getPut(),
|
||||
processedItem.getPatch(),
|
||||
processedItem.getHead(),
|
||||
processedItem.getOptions(),
|
||||
processedItem.getTrace())
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(
|
||||
operation -> {
|
||||
if (uniqueOperationIds.contains(operation.getOperationId())) {
|
||||
validationResult.getErrors()
|
||||
.add(
|
||||
new Invalid(
|
||||
ValidationRule.error("Non unique operationId", o -> null),
|
||||
"Non unique operationId",
|
||||
"Path: " + processedItem.get$ref() + " Operation:" + operation.getOperationId()));
|
||||
nonUniqueOperationIds.add(operation.getOperationId());
|
||||
uniqueOperationIds.add(operation.getOperationId());
|
||||
} else {
|
||||
uniqueOperationIds.add(operation.getOperationId());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (validationResult.getErrors().isEmpty() && validationResult.getWarnings().isEmpty()) {
|
||||
System.out.println("Validation complete. No validation errors or warning found. File is valid.");
|
||||
} else {
|
||||
System.out.println("Validation errors:");
|
||||
validationResult.getErrors().forEach(System.out::println);
|
||||
System.out.println("Validation warnings:");
|
||||
validationResult.getWarnings().forEach(w -> System.out.println("Severity: " + w.getSeverity().name() + "\nRule: " + w.getRule().getDescription() + "\nMessage:\n" + w.getMessage() + "\nDetails:" + w.getDetails()));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user