From c2d0b537e506b44af15891e6a0488723a05fc217 Mon Sep 17 00:00:00 2001 From: Eric Wittmann Date: Wed, 7 Aug 2019 16:58:02 -0400 Subject: [PATCH] improvements to the jax-rs code generator Signed-off-by: Eric Wittmann --- .../hub/api/codegen/OpenApi2JaxRs.java | 66 ++- .../codegen/beans/CodegenJavaArgument.java | 15 + .../api/codegen/beans/CodegenJavaBean.java | 15 + .../codegen/jaxrs/OpenApi2CodegenVisitor.java | 26 +- .../hub/api/codegen/util/SchemaSigner.java | 177 ++++++ .../main/resources/js-lib/OAI-codegen.umd.js | 556 ------------------ .../main/resources/js-lib/codegen-library.js | 12 - .../org/example/api/ArtifactsResource.java | 5 +- .../example/api/beans/ArtifactMetaData.java | 52 +- .../org/example/api/beans/ArtifactType.java | 49 ++ .../java/org/example/api/beans/Error.java | 48 ++ .../example/api/beans/VersionMetaData.java | 31 +- .../src/main/resources/META-INF/openapi.json | 109 +++- .../OpenApi2JaxRsTest/registry-api.json | 109 +++- .../org/example/api/TemplatesResource.java | 2 +- 15 files changed, 597 insertions(+), 675 deletions(-) create mode 100644 back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/util/SchemaSigner.java delete mode 100644 back-end/hub-codegen/src/main/resources/js-lib/OAI-codegen.umd.js delete mode 100644 back-end/hub-codegen/src/main/resources/js-lib/codegen-library.js create mode 100644 back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactType.java create mode 100644 back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/Error.java diff --git a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/OpenApi2JaxRs.java b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/OpenApi2JaxRs.java index fb0f3c40b..287ca4f55 100644 --- a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/OpenApi2JaxRs.java +++ b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/OpenApi2JaxRs.java @@ -191,16 +191,7 @@ protected void generateAll(CodegenInfo info, StringBuilder log, ZipOutputStream zipOutput.closeEntry(); } - for (CodegenJavaInterface iface : info.getInterfaces()) { - log.append("Generating Interface: " + iface.getPackage() + "." + iface.getName() + "\r\n"); - String javaInterface = generateJavaInterface(iface); - String javaInterfaceFileName = javaPackageToZipPath(iface.getPackage()) + iface.getName() + ".java"; - log.append("Adding to zip: " + javaInterfaceFileName + "\r\n"); - zipOutput.putNextEntry(new ZipEntry(javaInterfaceFileName)); - zipOutput.write(javaInterface.getBytes()); - zipOutput.closeEntry(); - } - + // Generate the java beans from data types IndexedCodeWriter codeWriter = new IndexedCodeWriter(); for (CodegenJavaBean bean : info.getBeans()) { log.append("Generating Bean: " + bean.getPackage() + "." + bean.getName() + "\r\n"); @@ -213,6 +204,18 @@ protected void generateAll(CodegenInfo info, StringBuilder log, ZipOutputStream zipOutput.write(codeWriter.get(key).getBytes()); zipOutput.closeEntry(); } + + // Generate the JAX-RS interfaces + for (CodegenJavaInterface iface : info.getInterfaces()) { + log.append("Generating Interface: " + iface.getPackage() + "." + iface.getName() + "\r\n"); + String javaInterface = generateJavaInterface(iface); + String javaInterfaceFileName = javaPackageToZipPath(iface.getPackage()) + iface.getName() + ".java"; + log.append("Adding to zip: " + javaInterfaceFileName + "\r\n"); + zipOutput.putNextEntry(new ZipEntry(javaInterfaceFileName)); + zipOutput.write(javaInterface.getBytes()); + zipOutput.closeEntry(); + } + } /** @@ -244,8 +247,39 @@ protected CodegenInfo getInfoFromApiDoc() throws IOException { // Then generate the CodegenInfo object. OpenApi2CodegenVisitor cgVisitor = new OpenApi2CodegenVisitor(this.settings.javaPackage, iVisitor.getInterfaces()); VisitorUtil.visitTree(document, cgVisitor, TraverserDirection.down); + + // Now resolve any inline schemas/types + CodegenInfo info = cgVisitor.getCodegenInfo(); + info.getInterfaces().forEach( iface -> { + iface.getMethods().forEach( method -> { + method.getArguments().forEach( arg -> { + String argTypeSig = arg.getTypeSignature(); + CodegenJavaBean matchingBean = findMatchingBean(info, argTypeSig); + if (matchingBean != null) { + arg.setType(matchingBean.getPackage() + "." + StringUtils.capitalize(matchingBean.getName())); + } + }); + }); + }); + + return info; + } - return cgVisitor.getCodegenInfo(); + /** + * Find a bean that matches the schema signature. + * @param info + * @param typeSignature + */ + private static CodegenJavaBean findMatchingBean(CodegenInfo info, String typeSignature) { + if (typeSignature == null) { + return null; + } + for (CodegenJavaBean bean : info.getBeans()) { + if (typeSignature.equals(bean.getSignature())) { + return bean; + } + } + return null; } /** @@ -332,6 +366,9 @@ private String generateJavaInterface(CodegenJavaInterface _interface) { } TypeName paramType = generateTypeName(cgArgument.getCollection(), cgArgument.getType(), cgArgument.getFormat(), cgArgument.getRequired(), defaultParamType); + if (cgArgument.getTypeSignature() != null) { + // TODO try to find a re-usable data type that matches the type signature + } com.squareup.javapoet.ParameterSpec.Builder paramBuilder = ParameterSpec.builder(paramType, paramNameToJavaArgName(cgArgument.getName())); if (cgArgument.getIn().equals("path")) { @@ -350,6 +387,10 @@ private String generateJavaInterface(CodegenJavaInterface _interface) { } } + // TODO:: error responses (4xx and 5xx) + // Should errors be modeled in some way? JAX-RS has a few ways to handle them. I'm inclined to + // not generate anything in the interface for error responses. + // Javadoc if (cgMethod.getDescription() != null) { methodBuilder.addJavadoc(cgMethod.getDescription()); @@ -374,8 +415,7 @@ private String generateJavaInterface(CodegenJavaInterface _interface) { * @param required * @param defaultType */ - private TypeName generateTypeName(String collection, String type, String format, Boolean required, - TypeName defaultType) { + private TypeName generateTypeName(String collection, String type, String format, Boolean required, TypeName defaultType) { if (type == null) { return defaultType; } diff --git a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaArgument.java b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaArgument.java index 5f6c8ba72..2e28b97a0 100644 --- a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaArgument.java +++ b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaArgument.java @@ -27,6 +27,7 @@ public class CodegenJavaArgument { private String type; private String format; private Boolean required; + private String typeSignature; /** * Constructor. @@ -118,4 +119,18 @@ public void setRequired(Boolean required) { this.required = required; } + /** + * @return the typeSignature + */ + public String getTypeSignature() { + return typeSignature; + } + + /** + * @param typeSignature the typeSignature to set + */ + public void setTypeSignature(String typeSignature) { + this.typeSignature = typeSignature; + } + } diff --git a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaBean.java b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaBean.java index 6d12f23d2..706499c46 100644 --- a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaBean.java +++ b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/beans/CodegenJavaBean.java @@ -26,6 +26,7 @@ public class CodegenJavaBean { private String _package; private String name; private JsonNode $schema; + private String signature; /** * Constructor. @@ -75,4 +76,18 @@ public void setName(String name) { this.$schema = $schema; } + /** + * @return the signature + */ + public String getSignature() { + return signature; + } + + /** + * @param signature the signature to set + */ + public void setSignature(String signature) { + this.signature = signature; + } + } diff --git a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/jaxrs/OpenApi2CodegenVisitor.java b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/jaxrs/OpenApi2CodegenVisitor.java index 480a884ad..8d8410a25 100644 --- a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/jaxrs/OpenApi2CodegenVisitor.java +++ b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/jaxrs/OpenApi2CodegenVisitor.java @@ -52,6 +52,7 @@ import io.apicurio.hub.api.codegen.beans.CodegenJavaInterface; import io.apicurio.hub.api.codegen.beans.CodegenJavaMethod; import io.apicurio.hub.api.codegen.beans.CodegenJavaReturn; +import io.apicurio.hub.api.codegen.util.SchemaSigner; /** * Visitor used to create a Codegen Info object from a OpenAPI document. @@ -71,6 +72,11 @@ public class OpenApi2CodegenVisitor extends CombinedVisitorAdapter { private boolean _processPathItemParams = false; + /** + * Constructor. + * @param packageName + * @param interfaces + */ public OpenApi2CodegenVisitor(String packageName, List interfaces) { this.codegenInfo.setName("Thorntail API"); this.codegenInfo.setVersion("1.0.0"); @@ -91,7 +97,18 @@ public OpenApi2CodegenVisitor(String packageName, List interfaces public CodegenInfo getCodegenInfo() { return this.codegenInfo; } - + + /** + * Creates a unique signature for the given schema. The signature is used to determine whether two schemas + * are the same. + * @param node + */ + private static String createSignature(OasSchema node) { + SchemaSigner signer = new SchemaSigner(); + Library.visitNode(node, signer); + return signer.getSignature(); + } + /** * @see io.apicurio.datamodels.combined.visitors.CombinedVisitorAdapter#visitInfo(io.apicurio.datamodels.core.models.common.Info) */ @@ -199,9 +216,12 @@ private void visit20Parameter(Oas20Parameter node) { if (cgReturn.getCollection() != null) { this._currentArgument.setCollection(cgReturn.getCollection()); } if (cgReturn.getType() != null) { this._currentArgument.setType(cgReturn.getType()); } if (cgReturn.getFormat() != null) { this._currentArgument.setFormat(cgReturn.getFormat()); } + + this._currentArgument.setTypeSignature(createSignature((OasSchema) node.schema)); } else if (node.type != null) { if (node.type != null) { this._currentArgument.setType(node.type); } if (node.format != null) { this._currentArgument.setFormat(node.format); } + // TODO:: sign the argument from the type and format on the node. } } private void visit30Parameter(Oas30Parameter node) { @@ -213,6 +233,7 @@ private void visit30Parameter(Oas30Parameter node) { if (cgReturn.getCollection() != null) { this._currentArgument.setCollection(cgReturn.getCollection()); } if (cgReturn.getType() != null) { this._currentArgument.setType(cgReturn.getType()); } if (cgReturn.getFormat() != null) { this._currentArgument.setFormat(cgReturn.getFormat()); } + this._currentArgument.setTypeSignature(createSignature((OasSchema) mediaType.schema)); } } else if (node.schema != null) { CodegenJavaReturn cgReturn = this.returnFromSchema((OasSchema) node.schema); @@ -220,6 +241,7 @@ private void visit30Parameter(Oas30Parameter node) { if (cgReturn.getCollection() != null) { this._currentArgument.setCollection(cgReturn.getCollection()); } if (cgReturn.getType() != null) { this._currentArgument.setType(cgReturn.getType()); } if (cgReturn.getFormat() != null) { this._currentArgument.setFormat(cgReturn.getFormat()); } + this._currentArgument.setTypeSignature(createSignature((OasSchema) node.schema)); } } } @@ -295,6 +317,8 @@ public void visitSchemaDefinition(IDefinition node) { bean.setName(name); bean.setPackage(this.packageName + ".beans"); bean.set$schema((JsonNode) Library.writeNode((Node) node)); + bean.setSignature(createSignature((OasSchema) node)); + this.codegenInfo.getBeans().add(bean); } diff --git a/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/util/SchemaSigner.java b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/util/SchemaSigner.java new file mode 100644 index 000000000..260eb68ff --- /dev/null +++ b/back-end/hub-codegen/src/main/java/io/apicurio/hub/api/codegen/util/SchemaSigner.java @@ -0,0 +1,177 @@ +/* + * Copyright 2019 Red Hat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apicurio.hub.api.codegen.util; + +import java.util.Arrays; + +import org.apache.commons.codec.digest.DigestUtils; + +import io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor; +import io.apicurio.datamodels.core.models.common.IDefinition; +import io.apicurio.datamodels.core.models.common.Schema; +import io.apicurio.datamodels.openapi.models.OasSchema; +import io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30AnyOfSchema; +import io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30NotSchema; +import io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30OneOfSchema; + +/** + * @author eric.wittmann@gmail.com + */ +public class SchemaSigner extends CombinedAllNodeVisitor { + + private StringBuilder sigSource = new StringBuilder(); + + /** + * Constructor. + */ + public SchemaSigner() { + } + + public String getSignature() { + if (this.sigSource.length() == 0) { + return null; + } + return DigestUtils.sha256Hex(this.sigSource.toString()); + } + + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitSchema(io.apicurio.datamodels.core.models.common.Schema) + */ + @Override + public void visitSchema(Schema node) { + OasSchema schema = (OasSchema) node; + // Right now we only support simple types. + if (schema.type != null && !schema.type.equals("object") && !schema.type.equals("array") && schema.$ref == null) { + // Type + this.sigSource.append("TYPE:"); + this.sigSource.append(schema.type); + // Format + if (schema.format != null) { + this.sigSource.append("|FORMAT:"); + this.sigSource.append(schema.format); + } + // Enum + if (schema.enum_ != null && schema.enum_.size() > 0) { + this.sigSource.append("|ENUM:"); + String[] options = schema.enum_.toArray(new String[schema.enum_.size()]); + Arrays.sort(options); + for (String option : options) { + this.sigSource.append(option); + this.sigSource.append(","); + } + } + + + // Max + if (schema.maximum != null) { + this.sigSource.append("|MAX:"); + this.sigSource.append(schema.maximum); + } + // Max Items + if (schema.maxItems != null) { + this.sigSource.append("|MAXITEMS:"); + this.sigSource.append(schema.maxItems); + } + // Max Length + if (schema.maxLength != null) { + this.sigSource.append("|MAXLENGTH:"); + this.sigSource.append(schema.maxLength); + } + // Min + if (schema.minimum != null) { + this.sigSource.append("|MIN:"); + this.sigSource.append(schema.minimum); + } + // Min Items + if (schema.minItems != null) { + this.sigSource.append("|MINITEMS:"); + this.sigSource.append(schema.minItems); + } + // Min Length + if (schema.minLength != null) { + this.sigSource.append("|MINLENGTH:"); + this.sigSource.append(schema.minLength); + } + // Min Properties + if (schema.minProperties != null) { + this.sigSource.append("|MINPROPS:"); + this.sigSource.append(schema.minProperties); + } + // Multiple Of + if (schema.multipleOf != null) { + this.sigSource.append("|MULTIPLEOF:"); + this.sigSource.append(schema.multipleOf); + } + // Pattern + if (schema.pattern != null) { + this.sigSource.append("|PATTERN:"); + this.sigSource.append(schema.pattern); + } + } + } + + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitAdditionalPropertiesSchema(io.apicurio.datamodels.openapi.models.OasSchema) + */ + @Override + public void visitAdditionalPropertiesSchema(OasSchema node) { + this.visitSchema(node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitAllOfSchema(io.apicurio.datamodels.openapi.models.OasSchema) + */ + @Override + public void visitAllOfSchema(OasSchema node) { + this.visitSchema(node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitAnyOfSchema(io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30AnyOfSchema) + */ + @Override + public void visitAnyOfSchema(Oas30AnyOfSchema node) { + this.visitSchema(node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitItemsSchema(io.apicurio.datamodels.openapi.models.OasSchema) + */ + @Override + public void visitItemsSchema(OasSchema node) { + this.visitSchema(node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitSchemaDefinition(io.apicurio.datamodels.core.models.common.IDefinition) + */ + @Override + public void visitSchemaDefinition(IDefinition node) { + this.visitSchema((OasSchema) node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitNotSchema(io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30NotSchema) + */ + @Override + public void visitNotSchema(Oas30NotSchema node) { + this.visitSchema(node); + } + /** + * @see io.apicurio.datamodels.combined.visitors.CombinedAllNodeVisitor#visitOneOfSchema(io.apicurio.datamodels.openapi.v3.models.Oas30Schema.Oas30OneOfSchema) + */ + @Override + public void visitOneOfSchema(Oas30OneOfSchema node) { + this.visitSchema(node); + } + +} diff --git a/back-end/hub-codegen/src/main/resources/js-lib/OAI-codegen.umd.js b/back-end/hub-codegen/src/main/resources/js-lib/OAI-codegen.umd.js deleted file mode 100644 index 4df4b8984..000000000 --- a/back-end/hub-codegen/src/main/resources/js-lib/OAI-codegen.umd.js +++ /dev/null @@ -1,556 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('oai-ts-core')) : - typeof define === 'function' && define.amd ? define(['exports', 'oai-ts-core'], factory) : - (global = global || self, factory(global.OAI_codegen = {}, global.OAI)); -}(this, function (exports, oaiTsCore) { 'use strict'; - - var __extends = (undefined && undefined.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - /** - * Visitor used to organize all of the paths into a set of interface names. - * - * TODO once everything is done, find all interfaces with only 1 path and pull them all into Root - */ - var InterfacesVisitor = /** @class */ (function (_super) { - __extends(InterfacesVisitor, _super); - function InterfacesVisitor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.interfaces = {}; - return _this; - } - InterfacesVisitor.prototype.getInterfaces = function () { - var rval = []; - for (var name_1 in this.interfaces) { - rval.push(this.interfaces[name_1]); - } - return rval; - }; - /** - * Visits a Path Item to produce - * @param {OasPathItem} node - */ - InterfacesVisitor.prototype.visitPathItem = function (node) { - var p = node.path(); - var split = p.split("/"); - if (split && split.length > 1) { - var firstSegment = split[1]; - if (firstSegment && firstSegment !== "" && firstSegment.indexOf("{") === -1) { - var iname = this.capitalize(firstSegment) + "Resource"; - this.addPathTo(p, iname); - return; - } - } - // Default. - this.addPathTo(p, "RootResource"); - }; - /** - * Adds a path to an interface. Creates the interface mapping if it doesn't exist yet. - * @param {string} path - * @param {string} interfaceName - */ - InterfacesVisitor.prototype.addPathTo = function (path, interfaceName) { - var info = this.interfaces[interfaceName]; - if (info === null || info === undefined) { - info = { - name: interfaceName, - paths: [] - }; - this.interfaces[interfaceName] = info; - } - info.paths.push(path); - }; - /** - * Capitalizes a word. - * @param {string} firstSegment - * @return {string} - */ - InterfacesVisitor.prototype.capitalize = function (firstSegment) { - return firstSegment.charAt(0).toUpperCase() + firstSegment.slice(1); - }; - return InterfacesVisitor; - }(oaiTsCore.OasCombinedVisitorAdapter)); - - var __extends$1 = (undefined && undefined.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - var PathItemDetectionVisitor = /** @class */ (function (_super) { - __extends$1(PathItemDetectionVisitor, _super); - function PathItemDetectionVisitor() { - return _super !== null && _super.apply(this, arguments) || this; - } - PathItemDetectionVisitor.prototype.visitPathItem = function (node) { - this.isPathItem = true; - }; - return PathItemDetectionVisitor; - }(oaiTsCore.OasCombinedVisitorAdapter)); - /** - * Visitor used to create a Codegen Info object from a OpenAPI document. - */ - var OpenApi2CodegenVisitor = /** @class */ (function (_super) { - __extends$1(OpenApi2CodegenVisitor, _super); - /** - * C'tor. - * @param {string} packageName - * @param {InterfaceInfo[]} interfaces - */ - function OpenApi2CodegenVisitor(packageName, interfaces) { - var _this = _super.call(this) || this; - _this.interfacesIndex = {}; - _this.codegenInfo = { - name: "Thorntail API", - version: "1.0.0", - interfaces: [], - beans: [] - }; - _this._library = new oaiTsCore.OasLibraryUtils(); - _this._methodCounter = 1; - _this._processPathItemParams = false; - _this.packageName = packageName; - for (var _i = 0, interfaces_1 = interfaces; _i < interfaces_1.length; _i++) { - var iface = interfaces_1[_i]; - for (var _a = 0, _b = iface.paths; _a < _b.length; _a++) { - var path = _b[_a]; - _this.interfacesIndex[path] = iface.name; - } - } - return _this; - } - /** - * Gets the CodegenInfo object that was created by the visitor. - * @return {CodegenInfo} - */ - OpenApi2CodegenVisitor.prototype.getCodegenInfo = function () { - return this.codegenInfo; - }; - /** - * Visits the info model to extract some meta data. - * @param {OasInfo} node - */ - OpenApi2CodegenVisitor.prototype.visitInfo = function (node) { - this.codegenInfo.name = node.title; - if (node.description) { - this.codegenInfo.description = node.description; - } - this.codegenInfo.version = node.version; - }; - /** - * Visits an operation to produce a CodegenJavaInterface. - * @param {OasPathItem} node - */ - OpenApi2CodegenVisitor.prototype.visitPathItem = function (node) { - var p = node.path(); - var cgInterface = this.getOrCreateInterface(p); - this._currentInterface = cgInterface; - }; - /** - * Visits an operation to produce a CodegenJavaMethod. - * @param {OasOperation} node - */ - OpenApi2CodegenVisitor.prototype.visitOperation = function (node) { - var method = { - name: this.methodName(node), - path: this.methodPath(node), - method: node.method(), - produces: [], - consumes: [], - arguments: [] - }; - if (node.description) { - method.description = node.description; - } - // Handle 2.0 "produces" - if (node.ownerDocument().is2xDocument()) { - var produces = node.produces; - if (produces === null || produces === undefined) { - produces = node.ownerDocument().produces; - } - if (produces) { - method.produces = produces; - } - } - // Handle 2.0 "consumes" - if (node.ownerDocument().is2xDocument()) { - var consumes = node.consumes; - if (consumes === null || consumes === undefined) { - consumes = node.ownerDocument().consumes; - } - if (consumes) { - method.consumes = consumes; - } - } - this._currentMethod = method; - this._currentInterface.methods.push(method); - // Be sure to process path and query parameters found on the parent! - this._processPathItemParams = true; - var parentParams = node.parent().parameters; - if (parentParams && parentParams.length > 0) { - for (var _i = 0, parentParams_1 = parentParams; _i < parentParams_1.length; _i++) { - var parentParam = parentParams_1[_i]; - oaiTsCore.OasVisitorUtil.visitNode(parentParam, this); - } - } - this._processPathItemParams = false; - }; - /** - * Visits a parameter to produce a CodegenJavaArgument. - * @param {Oas20Parameter | Oas30Parameter} node - */ - OpenApi2CodegenVisitor.prototype.visitParameter = function (node) { - // Skip processing of the parameter if it is defined at the path level. - if (!this._processPathItemParams && this.isPathItem(node.parent())) { - return; - } - var cgArgument = { - name: node.name, - in: node.in, - required: true - }; - this._currentMethod.arguments.push(cgArgument); - this._currentArgument = cgArgument; - if (node.required !== undefined && node.required !== null) { - cgArgument.required = node.required; - } - if (node.ownerDocument().is2xDocument()) { - this.visit20Parameter(node); - } - if (node.ownerDocument().is3xDocument()) { - this.visit30Parameter(node); - } - }; - OpenApi2CodegenVisitor.prototype.visit20Parameter = function (node) { - var cgReturn = this.returnFromSchema(node.schema); - if (cgReturn) { - if (cgReturn.collection) { - this._currentArgument.collection = cgReturn.collection; - } - if (cgReturn.type) { - this._currentArgument.type = cgReturn.type; - } - if (cgReturn.format) { - this._currentArgument.format = cgReturn.format; - } - } - else if (node.type) { - if (node.type) { - this._currentArgument.type = node.type; - } - if (node.format) { - this._currentArgument.format = node.format; - } - } - }; - OpenApi2CodegenVisitor.prototype.visit30Parameter = function (node) { - if (node.getMediaTypes().length > 0) { - var mediaTypes = node.getMediaTypes(); - if (mediaTypes && mediaTypes.length > 0) { - var mediaType = mediaTypes[0]; - var cgReturn = this.returnFromSchema(mediaType.schema); - if (cgReturn) { - if (cgReturn.collection) { - this._currentArgument.collection = cgReturn.collection; - } - if (cgReturn.type) { - this._currentArgument.type = cgReturn.type; - } - if (cgReturn.format) { - this._currentArgument.format = cgReturn.format; - } - } - } - } - else if (node.schema) { - this.visit20Parameter(node); - } - }; - /** - * Visits a requesty body to produce a CodegenJavaArgument with in === "body". - * @param {Oas30RequestBody} node - */ - OpenApi2CodegenVisitor.prototype.visitRequestBody = function (node) { - var mediaTypes = node.getMediaTypes(); - if (mediaTypes && mediaTypes.length > 0) { - var mediaType = mediaTypes[0]; - var cgArgument = { - name: "data", - in: "body", - required: true - }; - var cgReturn = this.returnFromSchema(mediaType.schema); - if (cgReturn) { - if (cgReturn.collection) { - cgArgument.collection = cgReturn.collection; - } - if (cgReturn.type) { - cgArgument.type = cgReturn.type; - } - if (cgReturn.format) { - cgArgument.format = cgReturn.format; - } - } - this._currentArgument = cgArgument; - this._currentMethod.arguments.push(cgArgument); - } - // Push all of the media types onto the "consumes" array for the method. - for (var _i = 0, mediaTypes_1 = mediaTypes; _i < mediaTypes_1.length; _i++) { - var mt = mediaTypes_1[_i]; - this._currentMethod.consumes.push(mt.name()); - } - }; - /** - * Visits a response to produce a CodegenJavaReturn for a method. - * @param {OasResponse} node - */ - OpenApi2CodegenVisitor.prototype.visitResponse = function (node) { - // Note: if there are multiple 2xx responses, only the first one will - // become the method return value. - if (node.statusCode() && node.statusCode().indexOf("2") === 0 && !this._currentMethod.return) { - if (node.ownerDocument().is2xDocument()) { - this.visit20Response(node); - } - if (node.ownerDocument().is3xDocument()) { - this.visit30Response(node); - } - } - }; - OpenApi2CodegenVisitor.prototype.visit20Response = function (node) { - if (node.statusCode() && node.statusCode().indexOf("2") === 0) { - this._currentMethod.return = this.returnFromSchema(node.schema); - } - }; - OpenApi2CodegenVisitor.prototype.visit30Response = function (node) { - var mediaTypes = node.getMediaTypes(); - if (mediaTypes && mediaTypes.length > 0) { - var mediaType = mediaTypes[0]; - this._currentMethod.return = this.returnFromSchema(mediaType.schema); - } - // Push all of the media types onto the "produces" array for the method. - for (var _i = 0, mediaTypes_2 = mediaTypes; _i < mediaTypes_2.length; _i++) { - var mt = mediaTypes_2[_i]; - this._currentMethod.produces.push(mt.name()); - } - }; - /** - * Visits a schema definition to produce a CodegenJavaBean. - * @param {Oas20SchemaDefinition | Oas30SchemaDefinition} node - */ - OpenApi2CodegenVisitor.prototype.visitSchemaDefinition = function (node) { - var name = null; - if (node.ownerDocument().is2xDocument()) { - name = node.definitionName(); - } - else if (node.ownerDocument().is3xDocument()) { - name = node.name(); - } - var bean = { - name: name, - package: this.packageName + ".beans", - $schema: this._library.writeNode(node) - }; - this.codegenInfo.beans.push(bean); - }; - OpenApi2CodegenVisitor.prototype.getOrCreateInterface = function (path) { - var interfaceName = this.interfacesIndex[path]; - for (var _i = 0, _a = this.codegenInfo.interfaces; _i < _a.length; _i++) { - var cgInterface_1 = _a[_i]; - if (cgInterface_1.name === interfaceName) { - return cgInterface_1; - } - } - var ifacePath = "/"; - if (interfaceName !== "Root") { - ifacePath = "/" + path.split("/")[1]; - } - var cgInterface = { - name: interfaceName, - package: this.packageName, - path: ifacePath, - methods: [] - }; - this.codegenInfo.interfaces.push(cgInterface); - return cgInterface; - }; - OpenApi2CodegenVisitor.prototype.methodName = function (operation) { - var _this = this; - if (operation.operationId !== null && operation.operationId !== undefined && operation.operationId.length > 0) { - return operation.operationId; - } - if (operation.summary !== null && operation.summary !== undefined && operation.summary.length > 0) { - var nameSegments = operation.summary.split(" "); - return this.decapitalize(nameSegments.map(function (segment) { - return _this.capitalize(segment.replace(/\W/g, '')); - }).join('')); - } - return "generatedMethod" + this._methodCounter++; - }; - OpenApi2CodegenVisitor.prototype.methodPath = function (operation) { - var path = operation.parent().path(); - if (path === this._currentInterface.path) { - return null; - } - path = path.substring(this._currentInterface.path.length); - if (path === "/") { - return null; - } - return path; - }; - OpenApi2CodegenVisitor.prototype.returnFromSchema = function (schema) { - if (schema === null || schema === undefined) { - return null; - } - var cgReturn = { - type: null - }; - if (schema.$ref) { - cgReturn.type = this.typeFromSchemaRef(schema.$ref); - } - else if (schema.type === "array") { - cgReturn.collection = "list"; - var items = schema.items; - var subReturn = this.returnFromSchema(items); - if (subReturn && subReturn.type) { - cgReturn.type = subReturn.type; - } - if (subReturn && subReturn.format) { - cgReturn.format = subReturn.format; - } - } - else { - if (schema.type) { - cgReturn.type = schema.type; - } - if (schema.format) { - cgReturn.format = schema.format; - } - } - return cgReturn; - }; - OpenApi2CodegenVisitor.prototype.typeFromSchemaRef = function (schemaRef) { - if (schemaRef && schemaRef.indexOf("#/components/schemas/") === 0) { - return this.packageName + ".beans." + schemaRef.substring(21); - } - if (schemaRef && schemaRef.indexOf("#/definitions/") === 0) { - return this.packageName + ".beans." + schemaRef.substring(14); - } - return null; - }; - OpenApi2CodegenVisitor.prototype.isPathItem = function (node) { - var viz = new PathItemDetectionVisitor(); - oaiTsCore.OasVisitorUtil.visitNode(node, viz); - return viz.isPathItem; - }; - /** - * Capitalizes a word. - * @param {string} word - * @return {string} - */ - OpenApi2CodegenVisitor.prototype.capitalize = function (word) { - return word.charAt(0).toUpperCase() + word.slice(1); - }; - /** - * De-capitalizes a word. - * @param {string} word - * @return {string} - */ - OpenApi2CodegenVisitor.prototype.decapitalize = function (word) { - return word.charAt(0).toLowerCase() + word.slice(1); - }; - return OpenApi2CodegenVisitor; - }(oaiTsCore.OasCombinedVisitorAdapter)); - - /** - * @license - * Copyright 2017 JBoss Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - var CodegenLibrary = /** @class */ (function () { - function CodegenLibrary() { - } - /** - * Called to generate a CodegenInfo from the given OAI document and Java package name. - * @param {OasDocument} document - * @param {string} javaPackage - * @return {CodegenInfo} - */ - CodegenLibrary.prototype.generateJaxRsInfo = function (document, javaPackage) { - // First, figure out the breakdown of the interfaces. - var visitor = new InterfacesVisitor(); - oaiTsCore.OasVisitorUtil.visitTree(document, visitor); - // Then generate the CodegenInfo object. - var cgVisitor = new OpenApi2CodegenVisitor(javaPackage, visitor.getInterfaces()); - oaiTsCore.OasVisitorUtil.visitTree(document, cgVisitor); - return cgVisitor.getCodegenInfo(); - }; - return CodegenLibrary; - }()); - - /** - * @license - * Copyright 2018 Red Hat - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - /** - * @license - * Copyright 2018 JBoss Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - exports.CodegenLibrary = CodegenLibrary; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); diff --git a/back-end/hub-codegen/src/main/resources/js-lib/codegen-library.js b/back-end/hub-codegen/src/main/resources/js-lib/codegen-library.js deleted file mode 100644 index 505d1c981..000000000 --- a/back-end/hub-codegen/src/main/resources/js-lib/codegen-library.js +++ /dev/null @@ -1,12 +0,0 @@ - -function executeCodegen(oaiDoc, javaPackage) { - console.debug("[codegen-library] Entering executeCommands"); - var library = new OAI.OasLibraryUtils(); - var oaiDocJSObj = JSON.parse(oaiDoc); - var document = library.createDocument(oaiDocJSObj); - - var cgLibrary = new OAI_codegen.CodegenLibrary(); - var codegenInfo = cgLibrary.generateJaxRsInfo(document, javaPackage); - - return JSON.stringify(codegenInfo, null, 2); -} diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/ArtifactsResource.java b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/ArtifactsResource.java index f6079802b..fd1e764f2 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/ArtifactsResource.java +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/ArtifactsResource.java @@ -14,6 +14,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Request; import org.example.api.beans.ArtifactMetaData; +import org.example.api.beans.ArtifactType; import org.example.api.beans.EditableMetaData; import org.example.api.beans.Rule; import org.example.api.beans.VersionMetaData; @@ -52,7 +53,7 @@ public interface ArtifactsResource { @Produces("application/json") @Consumes({"application/json", "application/x-yaml"}) ArtifactMetaData createArtifact( - @HeaderParam("X-Registry-ArtifactType") String xRegistryArtifactType, + @HeaderParam("X-Registry-ArtifactType") ArtifactType xRegistryArtifactType, @HeaderParam("X-Registry-ArtifactId") String xRegistryArtifactId, Request data); /** @@ -153,7 +154,7 @@ ArtifactMetaData createArtifact( @Produces("application/json") @Consumes({"application/json", "application/x-yaml"}) VersionMetaData createArtifactVersion(@PathParam("artifactId") String artifactId, - @HeaderParam("X-Registry-ArtifactType") String xRegistryArtifactType, Request data); + @HeaderParam("X-Registry-ArtifactType") ArtifactType xRegistryArtifactType, Request data); /** * Retrieves a single version of the artifact content. Both the `artifactId` and the diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactMetaData.java b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactMetaData.java index 04a54bb3e..f1f86ab7a 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactMetaData.java +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactMetaData.java @@ -2,14 +2,10 @@ package org.example.api.beans; import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.annotation.JsonValue; /** @@ -88,7 +84,7 @@ public class ArtifactMetaData { */ @JsonProperty("type") @JsonPropertyDescription("") - private ArtifactMetaData.Type type; + private ArtifactType type; /** * Identifier provided by the client. Must be globally unique. * @@ -243,7 +239,7 @@ public void setVersion(Integer version) { * */ @JsonProperty("type") - public ArtifactMetaData.Type getType() { + public ArtifactType getType() { return type; } @@ -253,7 +249,7 @@ public ArtifactMetaData.Type getType() { * */ @JsonProperty("type") - public void setType(ArtifactMetaData.Type type) { + public void setType(ArtifactType type) { this.type = type; } @@ -275,46 +271,4 @@ public void setClientId(String clientId) { this.clientId = clientId; } - public enum Type { - - AVRO("avro"), - PROTOBUFF("protobuff"), - JSON("json"), - OPENAPI("openapi"), - ASYNCAPI("asyncapi"); - private final String value; - private final static Map CONSTANTS = new HashMap(); - - static { - for (ArtifactMetaData.Type c: values()) { - CONSTANTS.put(c.value, c); - } - } - - private Type(String value) { - this.value = value; - } - - @Override - public String toString() { - return this.value; - } - - @JsonValue - public String value() { - return this.value; - } - - @JsonCreator - public static ArtifactMetaData.Type fromValue(String value) { - ArtifactMetaData.Type constant = CONSTANTS.get(value); - if (constant == null) { - throw new IllegalArgumentException(value); - } else { - return constant; - } - } - - } - } diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactType.java b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactType.java new file mode 100644 index 000000000..52873d747 --- /dev/null +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/ArtifactType.java @@ -0,0 +1,49 @@ + +package org.example.api.beans; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ArtifactType { + + AVRO("avro"), + PROTOBUFF("protobuff"), + JSON("json"), + OPENAPI("openapi"), + ASYNCAPI("asyncapi"); + private final String value; + private final static Map CONSTANTS = new HashMap(); + + static { + for (ArtifactType c: values()) { + CONSTANTS.put(c.value, c); + } + } + + private ArtifactType(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + @JsonValue + public String value() { + return this.value; + } + + @JsonCreator + public static ArtifactType fromValue(String value) { + ArtifactType constant = CONSTANTS.get(value); + if (constant == null) { + throw new IllegalArgumentException(value); + } else { + return constant; + } + } + +} diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/Error.java b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/Error.java new file mode 100644 index 000000000..63ba4505d --- /dev/null +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/Error.java @@ -0,0 +1,48 @@ + +package org.example.api.beans; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Root Type for Error + *

+ * All error responses, whether `4xx` or `5xx` will include one of these as the response + * body. + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "code", + "message" +}) +public class Error { + + @JsonProperty("code") + private Integer code; + @JsonProperty("message") + private String message; + + @JsonProperty("code") + public Integer getCode() { + return code; + } + + @JsonProperty("code") + public void setCode(Integer code) { + this.code = code; + } + + @JsonProperty("message") + public String getMessage() { + return message; + } + + @JsonProperty("message") + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/VersionMetaData.java b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/VersionMetaData.java index 6d761bf95..3e9c0492f 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/VersionMetaData.java +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/java/org/example/api/beans/VersionMetaData.java @@ -21,7 +21,8 @@ "description", "createdBy", "createdOn", - "id" + "id", + "type" }) public class VersionMetaData { @@ -58,6 +59,14 @@ public class VersionMetaData { @JsonProperty("id") @JsonPropertyDescription("") private Integer id; + /** + * + * (Required) + * + */ + @JsonProperty("type") + @JsonPropertyDescription("") + private ArtifactType type; /** * @@ -159,4 +168,24 @@ public void setId(Integer id) { this.id = id; } + /** + * + * (Required) + * + */ + @JsonProperty("type") + public ArtifactType getType() { + return type; + } + + /** + * + * (Required) + * + */ + @JsonProperty("type") + public void setType(ArtifactType type) { + this.type = type; + } + } diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/resources/META-INF/openapi.json b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/resources/META-INF/openapi.json index 9e2725ad2..e5518fcd0 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/resources/META-INF/openapi.json +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/_expected-registryApi-full/generated-api/src/main/resources/META-INF/openapi.json @@ -21,8 +21,12 @@ "requestBody": { "description": "The content of the artifact being created - this is often, but not always, JSON data\nrepresenting one of the supported artifact types:\n\n* Avro\n* Protobuff\n* JSON Schema\n* OpenAPI\n* AsyncAPI", "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -80,10 +84,17 @@ "responses": { "200": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "description": "The most recent version of the artifact." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "getLatestArtifact", @@ -93,8 +104,12 @@ "put": { "requestBody": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -111,6 +126,9 @@ } }, "description": "When successful, returns the updated artifact meta-data." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "updateArtifact", @@ -124,6 +142,9 @@ "responses": { "204": { "description": "Returned when the artifact was successfully deleted." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "deleteArtifact", @@ -181,8 +202,12 @@ "requestBody": { "description": "The content of the artifact version being created - this is often, but not always, JSON data\nrepresenting one of the supported artifact types:\n\n* Avro\n* Protobuff\n* JSON Schema\n* OpenAPI\n* AsyncAPI", "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -243,8 +268,12 @@ "responses": { "200": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "description": "The content of the artifact version." } @@ -758,7 +787,8 @@ "createdOn", "createdBy", "version", - "id" + "id", + "type" ], "type": "object", "properties": { @@ -783,11 +813,16 @@ "format": "int64", "description": "", "type": "integer" + }, + "type": { + "$ref": "#/components/schemas/ArtifactType", + "description": "" } }, "example": { "id": 12938472, "version": 12, + "type": "protobuff", "name": "Artifact Name", "description": "The description of the artifact", "createdBy": "user1", @@ -838,15 +873,8 @@ "type": "integer" }, "type": { - "description": "", - "enum": [ - "avro", - "protobuff", - "json", - "openapi", - "asyncapi" - ], - "type": "string" + "$ref": "#/components/schemas/ArtifactType", + "description": "" }, "clientId": { "description": "Identifier provided by the client. Must be globally unique.", @@ -885,6 +913,47 @@ "name": "UniqueRuleName", "config": "configuration_of_rule" } + }, + "ArtifactType": { + "description": "", + "enum": [ + "avro", + "protobuff", + "json", + "openapi", + "asyncapi" + ], + "type": "string" + }, + "Error": { + "title": "Root Type for Error", + "description": "All error responses, whether `4xx` or `5xx` will include one of these as the response\nbody.", + "type": "object", + "properties": { + "code": { + "format": "int32", + "type": "integer" + }, + "message": { + "type": "string" + } + }, + "example": { + "code": 12345, + "message": "An error occurred somewhere." + } + } + }, + "responses": { + "NotFound": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + }, + "description": "Common response for all operations that can return a `404` error." } } }, diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/registry-api.json b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/registry-api.json index 9e2725ad2..e5518fcd0 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/registry-api.json +++ b/back-end/hub-codegen/src/test/resources/OpenApi2JaxRsTest/registry-api.json @@ -21,8 +21,12 @@ "requestBody": { "description": "The content of the artifact being created - this is often, but not always, JSON data\nrepresenting one of the supported artifact types:\n\n* Avro\n* Protobuff\n* JSON Schema\n* OpenAPI\n* AsyncAPI", "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -80,10 +84,17 @@ "responses": { "200": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "description": "The most recent version of the artifact." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "getLatestArtifact", @@ -93,8 +104,12 @@ "put": { "requestBody": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -111,6 +126,9 @@ } }, "description": "When successful, returns the updated artifact meta-data." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "updateArtifact", @@ -124,6 +142,9 @@ "responses": { "204": { "description": "Returned when the artifact was successfully deleted." + }, + "404": { + "$ref": "#/components/responses/NotFound" } }, "operationId": "deleteArtifact", @@ -181,8 +202,12 @@ "requestBody": { "description": "The content of the artifact version being created - this is often, but not always, JSON data\nrepresenting one of the supported artifact types:\n\n* Avro\n* Protobuff\n* JSON Schema\n* OpenAPI\n* AsyncAPI", "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "required": true }, @@ -243,8 +268,12 @@ "responses": { "200": { "content": { - "application/json": {}, - "application/x-yaml": {} + "application/json": { + + }, + "application/x-yaml": { + + } }, "description": "The content of the artifact version." } @@ -758,7 +787,8 @@ "createdOn", "createdBy", "version", - "id" + "id", + "type" ], "type": "object", "properties": { @@ -783,11 +813,16 @@ "format": "int64", "description": "", "type": "integer" + }, + "type": { + "$ref": "#/components/schemas/ArtifactType", + "description": "" } }, "example": { "id": 12938472, "version": 12, + "type": "protobuff", "name": "Artifact Name", "description": "The description of the artifact", "createdBy": "user1", @@ -838,15 +873,8 @@ "type": "integer" }, "type": { - "description": "", - "enum": [ - "avro", - "protobuff", - "json", - "openapi", - "asyncapi" - ], - "type": "string" + "$ref": "#/components/schemas/ArtifactType", + "description": "" }, "clientId": { "description": "Identifier provided by the client. Must be globally unique.", @@ -885,6 +913,47 @@ "name": "UniqueRuleName", "config": "configuration_of_rule" } + }, + "ArtifactType": { + "description": "", + "enum": [ + "avro", + "protobuff", + "json", + "openapi", + "asyncapi" + ], + "type": "string" + }, + "Error": { + "title": "Root Type for Error", + "description": "All error responses, whether `4xx` or `5xx` will include one of these as the response\nbody.", + "type": "object", + "properties": { + "code": { + "format": "int32", + "type": "integer" + }, + "message": { + "type": "string" + } + }, + "example": { + "code": 12345, + "message": "An error occurred somewhere." + } + } + }, + "responses": { + "NotFound": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + }, + "description": "Common response for all operations that can return a `404` error." } } }, diff --git a/back-end/hub-codegen/src/test/resources/OpenApi2ThorntailTest/_expected-rda/src/main/java/org/example/api/TemplatesResource.java b/back-end/hub-codegen/src/test/resources/OpenApi2ThorntailTest/_expected-rda/src/main/java/org/example/api/TemplatesResource.java index 3880f3e10..ea21cdb94 100644 --- a/back-end/hub-codegen/src/test/resources/OpenApi2ThorntailTest/_expected-rda/src/main/java/org/example/api/TemplatesResource.java +++ b/back-end/hub-codegen/src/test/resources/OpenApi2ThorntailTest/_expected-rda/src/main/java/org/example/api/TemplatesResource.java @@ -38,7 +38,7 @@ public interface TemplatesResource { @GET @Produces("application/json") Response thisIsTheSearchEndpointUseAGETRequestAlongWithParametersToSearchForMetadataOnTemplates( - @QueryParam("tag") String tag, @QueryParam("free-text") String free_text, + @QueryParam("tag") String tag, @QueryParam("free-text") String freeText, @QueryParam("author") String author); /**