From 7571611cc248340e3af51b3fa85649e650cff678 Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Wed, 4 Mar 2020 13:38:44 +0100 Subject: [PATCH 1/3] Semver versioning Added option to disable Java Type Extensions --- boat-diff/pom.xml | 2 +- boat-engine/pom.xml | 2 +- .../java/com/backbase/oss/boat/Exporter.java | 21 +++++++++-------- .../oss/boat/JsonSchemaToOpenApi.java | 23 +++++++++++-------- boat-maven-plugin/pom.xml | 2 +- boat-terminal/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/boat-diff/pom.xml b/boat-diff/pom.xml index 2a4b9dfc5..f9e6437cf 100644 --- a/boat-diff/pom.xml +++ b/boat-diff/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.1.0.0 + 0.1.1-SNAPSHOT boat-diff diff --git a/boat-engine/pom.xml b/boat-engine/pom.xml index 87b9e7ab2..cdd559df0 100644 --- a/boat-engine/pom.xml +++ b/boat-engine/pom.xml @@ -8,7 +8,7 @@ com.backbase.oss backbase-openapi-tools - 0.1.0.0 + 0.1.1-SNAPSHOT boat-engine jar diff --git a/boat-engine/src/main/java/com/backbase/oss/boat/Exporter.java b/boat-engine/src/main/java/com/backbase/oss/boat/Exporter.java index 6d1a0b048..d33d2f41f 100644 --- a/boat-engine/src/main/java/com/backbase/oss/boat/Exporter.java +++ b/boat-engine/src/main/java/com/backbase/oss/boat/Exporter.java @@ -81,21 +81,21 @@ public class Exporter { public static final String NO_DESCRIPTION_AVAILABLE = "No description available"; private static ObjectMapper mapper = Utils.createObjectMapper(); - private static boolean convertJsonExamplesToYaml; + private static boolean addJavaTypeExtensions; private Exporter() { throw new AssertionError("Private constructor"); } - public static OpenAPI export(File inputFile, boolean convertJsonExamplesToYaml, List transformers) + public static OpenAPI export(File inputFile, boolean addJavaTypeExtensions, List transformers) throws ExportException { - OpenAPI exported = export(inputFile, convertJsonExamplesToYaml); + OpenAPI exported = export(inputFile, addJavaTypeExtensions); transformers.forEach(transformer -> transformer.transform(exported, new HashMap())); return exported; } - public static OpenAPI export(File inputFile, boolean convertJsonExamplesToYaml) throws ExportException { + public static OpenAPI export(File inputFile, boolean addJavaTypeExtensions) throws ExportException { // Guess Service Name AtomicReference serviceName = new AtomicReference<>("serviceName"); @@ -105,12 +105,11 @@ public static OpenAPI export(File inputFile, boolean convertJsonExamplesToYaml) .findFirst() .ifPresent(s -> serviceName.set(s.replaceAll("-spec", "-service"))); - return export(serviceName.get(), inputFile, convertJsonExamplesToYaml); + return export(serviceName.get(), inputFile, addJavaTypeExtensions); } - public static OpenAPI export(String serviceName, File inputFile, boolean convertJsonExamplesToYaml) + public static OpenAPI export(String serviceName, File inputFile, boolean addJavaTypeExtensions) throws ExportException { - Exporter.convertJsonExamplesToYaml = convertJsonExamplesToYaml; File parentFile = inputFile.getParentFile(); URL baseUrl; @@ -142,9 +141,13 @@ public static OpenAPI export(String serviceName, File inputFile, boolean convert Components components = new Components(); components.setSchemas(new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); - JsonSchemaToOpenApi jsonSchemaToOpenApi = new JsonSchemaToOpenApi(baseUrl, components, ramlTypeReferences, - convertJsonExamplesToYaml); + JsonSchemaToOpenApi jsonSchemaToOpenApi = new JsonSchemaToOpenApi( + baseUrl, + components, + ramlTypeReferences, + addJavaTypeExtensions); + assert ramlApi != null; Map types = collectTypesFromRamlSpec(ramlApi); List operations = new ArrayList<>(); diff --git a/boat-engine/src/main/java/com/backbase/oss/boat/JsonSchemaToOpenApi.java b/boat-engine/src/main/java/com/backbase/oss/boat/JsonSchemaToOpenApi.java index 9b0817a4b..54d312cc7 100644 --- a/boat-engine/src/main/java/com/backbase/oss/boat/JsonSchemaToOpenApi.java +++ b/boat-engine/src/main/java/com/backbase/oss/boat/JsonSchemaToOpenApi.java @@ -59,17 +59,18 @@ class JsonSchemaToOpenApi { private final URL baseUrl; private final Components components; private final Map ramlTypeReferences; - private final boolean convertJsonExamplesToYaml; + private final boolean addJavaTypeExtensions; private ObjectMapper objectMapper = new ObjectMapper(); - public JsonSchemaToOpenApi(URL baseUrl, Components components, Map ramlTypeReferences, boolean convertJsonExamplesToYaml) { + public JsonSchemaToOpenApi(URL baseUrl, Components components, Map ramlTypeReferences, boolean addJavaTypeExtensions) { + this.baseUrl = baseUrl; this.components = components; this.jsonSchemas = new TreeMap<>(); this.referenceNames = HashBiMap.create(); this.ramlTypeReferences = ramlTypeReferences; - this.convertJsonExamplesToYaml = convertJsonExamplesToYaml; + this.addJavaTypeExtensions = addJavaTypeExtensions; } private Map jsonSchemas; @@ -106,7 +107,7 @@ public Schema convert(String name, JSONTypeDeclaration typeDeclaration) throws E if (schema == null) { referenceNames.put(baseUrl.toString() + "/" + name + ".raml", name); schema = createNewSchema(null, jsonSchema, name, components, baseUrl); - schema.setExample(ExampleUtils.getExampleObject(typeDeclaration.example(), convertJsonExamplesToYaml)); + schema.setExample(ExampleUtils.getExampleObject(typeDeclaration.example(), true)); components.addSchemas(name, schema); } log.debug("Created new schema from: {} as: {}", name, schemaName); @@ -118,7 +119,7 @@ public Schema convert(String name, JSONTypeDeclaration typeDeclaration) throws E throw new ExportException("Cannot dereference json schema from type: " + typeDeclaration.name(), e); } - schema.setExample(ExampleUtils.getExampleObject(typeDeclaration.example(), convertJsonExamplesToYaml)); + schema.setExample(ExampleUtils.getExampleObject(typeDeclaration.example(), true)); return schema; @@ -283,11 +284,13 @@ public Schema createNewSchema(Schema parent, JsonNode type, String name, Compone $ref = getReferenceFromParent($ref, parent); } schema.set$ref($ref); - if (type.hasNonNull(JAVA_TYPE)) { - schema.addExtension(X_JAVA_TYPE, type.get(JAVA_TYPE).textValue()); - } - if (type.hasNonNull("javaEnumNames")) { - schema.addExtension("x-java-enum-names", getEnum(type, "javaEnumNames")); + if (addJavaTypeExtensions) { + if (type.hasNonNull(JAVA_TYPE)) { + schema.addExtension(X_JAVA_TYPE, type.get(JAVA_TYPE).textValue()); + } + if (type.hasNonNull("javaEnumNames")) { + schema.addExtension("x-java-enum-names", getEnum(type, "javaEnumNames")); + } } schema.setEnum(getEnum(type)); return schema; diff --git a/boat-maven-plugin/pom.xml b/boat-maven-plugin/pom.xml index 26b3ce200..04056532c 100644 --- a/boat-maven-plugin/pom.xml +++ b/boat-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.1.0.0 + 0.1.1-SNAPSHOT boat-maven-plugin diff --git a/boat-terminal/pom.xml b/boat-terminal/pom.xml index 06a49ed3d..8930af09e 100644 --- a/boat-terminal/pom.xml +++ b/boat-terminal/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.1.0.0 + 0.1.1-SNAPSHOT boat-terminal diff --git a/pom.xml b/pom.xml index 3d78c900a..2924c431b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.backbase.oss backbase-openapi-tools - 0.1.0.0 + 0.1.1-SNAPSHOT pom Backbase Open Api Tools will help you converting RAML to OpenAPI plus many more From 195148f1c5af464cbea825af9b73ecb1e09cdc1a Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Wed, 4 Mar 2020 19:47:50 +0100 Subject: [PATCH 2/3] Semver versioning Added option to disable Java Type Extensions Additional Properties can now be configured to add the dynamic property to a predefined list of schem names. RAML does not support this OOTB --- .../AdditionalPropertiesAdder.java | 29 +++++++++++++++++++ boat-maven-plugin/README.md | 5 ++++ .../oss/boat/AbstractRamlToOpenApi.java | 27 +++++------------ .../com/backbase/oss/boat/ExportBomMojo.java | 2 +- .../com/backbase/oss/boat/ExportMojo.java | 2 +- 5 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 boat-engine/src/main/java/com/backbase/oss/boat/transformers/AdditionalPropertiesAdder.java diff --git a/boat-engine/src/main/java/com/backbase/oss/boat/transformers/AdditionalPropertiesAdder.java b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/AdditionalPropertiesAdder.java new file mode 100644 index 000000000..a48647b18 --- /dev/null +++ b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/AdditionalPropertiesAdder.java @@ -0,0 +1,29 @@ +package com.backbase.oss.boat.transformers; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.ObjectSchema; +import java.util.HashMap; +import java.util.List; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AdditionalPropertiesAdder implements Transformer { + + private final List schemaNames; + + public AdditionalPropertiesAdder(List schemaNames) { + this.schemaNames = schemaNames; + } + + @Override + public void transform(OpenAPI openAPI, HashMap options) { + openAPI.getComponents().getSchemas().values().stream() + .filter(schema -> schemaNames.contains(schema.getName())) + .forEach(schema -> { + log.info("Adding property: \"additions\" to Schema: {}", schema.getName()); + ObjectSchema propertiesItem = new ObjectSchema(); + propertiesItem.setAdditionalProperties(true); + schema.addProperties("additions", propertiesItem); + }); + } +} diff --git a/boat-maven-plugin/README.md b/boat-maven-plugin/README.md index c52fae107..6daf5678c 100644 --- a/boat-maven-plugin/README.md +++ b/boat-maven-plugin/README.md @@ -11,6 +11,7 @@ Finds files name `api.raml`, `client-api.raml` or `service-api.raml`. Processes these files (and the json schemes they refer to) to produce `open-api.yaml` files in the output directory. Configuration example + ```$xml @@ -33,6 +34,10 @@ Configuration example mock-api-server + + User + UserItem + diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java index e82d30db5..23348504d 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java @@ -1,6 +1,7 @@ package com.backbase.oss.boat; import com.backbase.oss.boat.serializer.SerializerUtils; +import com.backbase.oss.boat.transformers.AdditionalPropertiesAdder; import com.backbase.oss.boat.transformers.Decomposer; import com.backbase.oss.boat.transformers.Deprecator; import com.backbase.oss.boat.transformers.Transformer; @@ -16,7 +17,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -26,7 +26,6 @@ import java.util.Optional; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -58,17 +57,12 @@ abstract class AbstractRamlToOpenApi extends AbstractMojo { @Parameter(property = "includeGroupId", defaultValue = "com.backbase.") protected String includeGroupIds; - @Parameter(property = "includeArtifactIds", defaultValue = "presentation,integration,persistence,pandp") - protected String includeArtifactIds; - - @Parameter(property = "xLogoUrl") protected String xLogoUrl; @Parameter(property = "xLogoAltText") protected String xLogoAltText; - @Parameter(property = "licenseName") protected String licenseName; @@ -87,7 +81,6 @@ abstract class AbstractRamlToOpenApi extends AbstractMojo { @Parameter(property = "convertJsonExamplesToYaml", defaultValue = "true") protected boolean convertJsonExamplesToYaml; - @Parameter(property = "appendDeprecatedMetadataInDescription", defaultValue = "true") protected boolean appendDeprecatedMetadataInDescription = true; @@ -100,6 +93,9 @@ abstract class AbstractRamlToOpenApi extends AbstractMojo { @Parameter(property = "includeVersionInOutputDirectory", defaultValue = "true") protected boolean includeVersionInOutputDirectory; + @Parameter(property = "addAdditionalProperties") + protected List addAdditionalProperties = new ArrayList<>(); + /** * Target directory for generated code. Use location relative to the project.baseDir. Default value @@ -169,6 +165,9 @@ protected OpenAPI convert(String name, Optional version, File ramlFile) if (decompose) { transformers.add(new Decomposer()); } + if( !addAdditionalProperties.isEmpty()) { + transformers.add(new AdditionalPropertiesAdder(addAdditionalProperties)); + } OpenAPI openApi = Exporter.export(ramlFile, convertJsonExamplesToYaml, transformers); pimpInfo(name, version, ramlFile, openApi); @@ -324,14 +323,6 @@ protected void writeSwaggerUrls(File outputDir) throws MojoExecutionException { } } - protected boolean isSpecification(Artifact artifact) { - return Arrays.stream(includeArtifactIds.split(",")) - .filter(StringUtils::isNotEmpty) - .anyMatch(artifactId -> { - return artifact.getArtifactId().contains(artifactId); - }); - } - public void setProject(MavenProject project) { this.project = project; } @@ -401,10 +392,6 @@ public void setIncludeGroupIds(String includeGroupIds) { this.includeGroupIds = includeGroupIds; } - public void setIncludeArtifactIds(String includeArtifactIds) { - this.includeArtifactIds = includeArtifactIds; - } - public void setxLogoUrl(String xLogoUrl) { this.xLogoUrl = xLogoUrl; } diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportBomMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportBomMojo.java index 5d710b843..cadd35aec 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportBomMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportBomMojo.java @@ -37,7 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Mojo(name = "raml2openapi-bom", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true) +@Mojo(name = "export-bom", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true) public class ExportBomMojo extends AbstractRamlToOpenApi { public static final String X_CHANGELOG = "x-changelog"; diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportMojo.java index 901d643a8..630fc9a19 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/ExportMojo.java @@ -8,7 +8,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; -@Mojo(name = "raml2openapi", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true) +@Mojo(name = "export", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true) public class ExportMojo extends AbstractRamlToOpenApi { @Override From d16e6da23af70ef67bbd6470c987400bdaeef980 Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Wed, 4 Mar 2020 20:06:04 +0100 Subject: [PATCH 3/3] Added a LicenseAdder to Add Licenses with the LicenseAdder to Add Licenses --- .../oss/boat/transformers/LicenseAdder.java | 26 ++++++++ .../oss/boat/AbstractRamlToOpenApi.java | 61 +++++++++++-------- 2 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 boat-engine/src/main/java/com/backbase/oss/boat/transformers/LicenseAdder.java diff --git a/boat-engine/src/main/java/com/backbase/oss/boat/transformers/LicenseAdder.java b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/LicenseAdder.java new file mode 100644 index 000000000..3007e5373 --- /dev/null +++ b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/LicenseAdder.java @@ -0,0 +1,26 @@ +package com.backbase.oss.boat.transformers; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.License; +import java.util.HashMap; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class LicenseAdder implements Transformer { + + public LicenseAdder(String licenseName, String licenseUrl) { + this.licenseName = licenseName; + this.licenseUrl = licenseUrl; + } + + private final String licenseName; + private final String licenseUrl; + + @Override + public void transform(OpenAPI openAPI, HashMap options) { + if (openAPI.getInfo().getLicense() == null) { + openAPI.getInfo().setLicense(new License().name(licenseName).url(licenseUrl)); + log.info("Adding License: {} with url: {} to Schema: {}", licenseName, licenseUrl, openAPI.getInfo().getTitle()); + } + } +} diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java index 23348504d..385a045e3 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractRamlToOpenApi.java @@ -4,6 +4,7 @@ import com.backbase.oss.boat.transformers.AdditionalPropertiesAdder; import com.backbase.oss.boat.transformers.Decomposer; import com.backbase.oss.boat.transformers.Deprecator; +import com.backbase.oss.boat.transformers.LicenseAdder; import com.backbase.oss.boat.transformers.Transformer; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.models.OpenAPI; @@ -125,8 +126,8 @@ abstract class AbstractRamlToOpenApi extends AbstractMojo { protected boolean isRamlSpec(File file) { return file.getName().equals("api.raml") - || file.getName().equals("service-api.raml") - || file.getName().equals("client-api.raml"); + || file.getName().equals("service-api.raml") + || file.getName().equals("client-api.raml"); } protected File export(String name, Optional version, File ramlFile, File outputDirectory) throws ExportException, IOException { @@ -165,32 +166,36 @@ protected OpenAPI convert(String name, Optional version, File ramlFile) if (decompose) { transformers.add(new Decomposer()); } - if( !addAdditionalProperties.isEmpty()) { + if (!addAdditionalProperties.isEmpty()) { transformers.add(new AdditionalPropertiesAdder(addAdditionalProperties)); } + if (licenseName != null && licenseUrl != null) { + transformers.add(new LicenseAdder(licenseName, licenseUrl)); + } + OpenAPI openApi = Exporter.export(ramlFile, convertJsonExamplesToYaml, transformers); pimpInfo(name, version, ramlFile, openApi); if (appendDeprecatedMetadataInDescription) { // Iterate over all operations and update the description openApi.getPaths().values().stream().forEach(pathItem -> { pathItem.readOperationsMap().entrySet().stream() - .filter(this::isDeprecated) - .forEach(httpMethodOperationEntry -> { - Operation operation = httpMethodOperationEntry.getValue(); - Optional deprecatedInformationOptional = generateMarkdownForDeprecationExtention(operation); - - deprecatedInformationOptional.ifPresent(deprecatedInformation -> { - log.debug("Inserting deprecated information: \n{}", deprecatedInformation); - if (operation.getDescription() == null) { - operation.setDescription(deprecatedInformation); - } else { - operation.setDescription(operation.getDescription() + "\n" + deprecatedInformation); - } - }); - pathItem.operation(httpMethodOperationEntry.getKey(), operation); + .filter(this::isDeprecated) + .forEach(httpMethodOperationEntry -> { + Operation operation = httpMethodOperationEntry.getValue(); + Optional deprecatedInformationOptional = generateMarkdownForDeprecationExtention(operation); + + deprecatedInformationOptional.ifPresent(deprecatedInformation -> { + log.debug("Inserting deprecated information: \n{}", deprecatedInformation); + if (operation.getDescription() == null) { + operation.setDescription(deprecatedInformation); + } else { + operation.setDescription(operation.getDescription() + "\n" + deprecatedInformation); } - ); + }); + pathItem.operation(httpMethodOperationEntry.getKey(), operation); + } + ); }); } return openApi; @@ -235,8 +240,8 @@ private Optional generateMarkdownForDeprecationExtention(Operation opera private void pimpInfo(String name, Optional version, File ramlFile, OpenAPI openApi) { Info info = openApi.getInfo(); String apiName = name + " - " - + info.getTitle() + " - " - + StringUtils.substringBeforeLast(ramlFile.getName(), "."); + + info.getTitle() + " - " + + StringUtils.substringBeforeLast(ramlFile.getName(), "."); // info.setTitle(apiName); version.ifPresent(info::setVersion); @@ -432,9 +437,13 @@ public void setOutput(File output) { this.output = output; } - public List getServers() { return servers; } + public List getServers() { + return servers; + } - public void setServers(List servers) { this.servers = servers; } + public void setServers(List servers) { + this.servers = servers; + } public ArtifactResult resolveArtifactFromRepositories(org.eclipse.aether.artifact.Artifact artifact) { ArtifactRequest artifactRequest = getArtifactRequest(artifact); @@ -456,10 +465,10 @@ private ArtifactRequest getArtifactRequest(org.eclipse.aether.artifact.Artifact protected DefaultArtifact createNewDefaultArtifact(Dependency dependency) { return new DefaultArtifact(dependency.getGroupId() - , dependency.getArtifactId() - , (org.codehaus.plexus.util.StringUtils.isNotEmpty(dependency.getClassifier()) ? dependency.getClassifier() : null) - , (org.codehaus.plexus.util.StringUtils.isNotEmpty(dependency.getType()) ? dependency.getType() : null) - , dependency.getVersion()); + , dependency.getArtifactId() + , (org.codehaus.plexus.util.StringUtils.isNotEmpty(dependency.getClassifier()) ? dependency.getClassifier() : null) + , (org.codehaus.plexus.util.StringUtils.isNotEmpty(dependency.getType()) ? dependency.getType() : null) + , dependency.getVersion()); }