From e88663218757e2662a9389f66bda5248f16f34ab Mon Sep 17 00:00:00 2001 From: lnash94 Date: Tue, 22 Aug 2023 15:54:18 +0530 Subject: [PATCH] Resolve conflict and apply project API changes --- .../diagnostic/DiagnosticMessages.java | 6 +- .../service/ConstraintAnnotation.java | 7 +- .../service/ModuleMemberVisitor.java | 11 ++- .../service/OpenAPIComponentMapper.java | 73 ++++++++++++------- .../service/OpenAPIHeaderMapper.java | 11 ++- .../service/OpenAPIParameterMapper.java | 28 ++++--- .../service/OpenAPIQueryParameterMapper.java | 30 ++++---- .../service/OpenAPIRequestBodyMapper.java | 16 ++-- .../service/OpenAPIResourceMapper.java | 8 +- .../service/OpenAPIResponseMapper.java | 9 ++- .../service/OpenAPIServiceMapper.java | 6 +- .../converter/utils/ConverterCommonUtils.java | 5 +- .../utils/ServiceToOpenAPIConverterUtils.java | 12 +-- .../generators/openapi/ConstraintTests.java | 24 +++--- .../openapi/ModuleReferenceTests.java | 4 +- .../expected_gen/arrayTypeResponse.yaml | 1 + .../expected_gen/constraint/array.yaml | 30 +++++++- .../expected_gen/constraint/record_field.yaml | 28 ++++++- 18 files changed, 197 insertions(+), 112 deletions(-) diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/diagnostic/DiagnosticMessages.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/diagnostic/DiagnosticMessages.java index 4979795fe..a09dbeca0 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/diagnostic/DiagnosticMessages.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/diagnostic/DiagnosticMessages.java @@ -61,11 +61,9 @@ public enum DiagnosticMessages { DiagnosticSeverity.WARNING), OAS_CONVERTOR_114("OAS_CONVERTOR_114", "Generated OpenAPI definition does not contain information " + "for Ballerina type '%s'. ", DiagnosticSeverity.WARNING), - OAS_CONVERTOR_115("OAS_CONVERTOR_115", "Failed to parser the Number value due to: %s ", - DiagnosticSeverity.ERROR), - "for Ballerina type '%s'. ", DiagnosticSeverity.WARNING), -//todo resolve conflicts OAS_CONVERTOR_115("OAS_CONVERTOR_115", "Given Ballerina file does not contain any HTTP service.", + DiagnosticSeverity.ERROR), + OAS_CONVERTOR_116("OAS_CONVERTOR_116", "Failed to parser the Number value due to: %s ", DiagnosticSeverity.ERROR); private final String code; diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ConstraintAnnotation.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ConstraintAnnotation.java index b8b403051..44121cd2a 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ConstraintAnnotation.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ConstraintAnnotation.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com). * - * WSO2 Inc. licenses this file to you under the Apache License, + * WSO2 LLC. licenses this file to you 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 @@ -20,8 +20,9 @@ import java.util.Optional; /** + * This @link ConstraintAnnotation} class represents the constraint annotations. * - * @since 1.2.0 + * @since 1.9.0 */ public class ConstraintAnnotation { private final String minValue; diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ModuleMemberVisitor.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ModuleMemberVisitor.java index 252325a26..565d21b3d 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ModuleMemberVisitor.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/ModuleMemberVisitor.java @@ -22,8 +22,7 @@ import io.ballerina.compiler.syntax.tree.NodeVisitor; import io.ballerina.compiler.syntax.tree.TypeDefinitionNode; -import java.util.LinkedList; -import java.util.List; +import java.util.LinkedHashSet; /** * Visitor to get the TypeDefinitionNode and ListenerDeclarationNodes. @@ -32,8 +31,8 @@ */ public class ModuleMemberVisitor extends NodeVisitor { - LinkedList typeDefinitionNodes = new LinkedList<>(); - LinkedList listenerDeclarationNodes = new LinkedList<>(); + LinkedHashSet typeDefinitionNodes = new LinkedHashSet<>(); + LinkedHashSet listenerDeclarationNodes = new LinkedHashSet<>(); @Override public void visit(TypeDefinitionNode typeDefinitionNode) { @@ -45,11 +44,11 @@ public void visit(ListenerDeclarationNode listenerDeclarationNode) { listenerDeclarationNodes.add(listenerDeclarationNode); } - public List getTypeDefinitionNodes() { + public LinkedHashSet getTypeDefinitionNodes() { return typeDefinitionNodes; } - public List getListenerDeclarationNodes() { + public LinkedHashSet getListenerDeclarationNodes() { return listenerDeclarationNodes; } } diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIComponentMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIComponentMapper.java index 32c5e155a..a4c9b6f26 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIComponentMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIComponentMapper.java @@ -38,14 +38,15 @@ import io.ballerina.compiler.api.symbols.UnionTypeSymbol; import io.ballerina.compiler.syntax.tree.AnnotationNode; import io.ballerina.compiler.syntax.tree.ExpressionNode; +import io.ballerina.compiler.syntax.tree.IntersectionTypeDescriptorNode; import io.ballerina.compiler.syntax.tree.MappingConstructorExpressionNode; import io.ballerina.compiler.syntax.tree.MappingFieldNode; import io.ballerina.compiler.syntax.tree.MetadataNode; -import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.NodeList; -import io.ballerina.compiler.syntax.tree.NonTerminalNode; import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; import io.ballerina.compiler.syntax.tree.RecordFieldNode; +import io.ballerina.compiler.syntax.tree.RecordTypeDescriptorNode; import io.ballerina.compiler.syntax.tree.SpecificFieldNode; import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.TypeDefinitionNode; @@ -70,6 +71,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -89,14 +91,13 @@ public class OpenAPIComponentMapper { private final Components components; private final List diagnostics; - private final NonTerminalNode rootNode; private final HashSet visitedTypeDefinitionNames = new HashSet<>(); + private final LinkedHashSet typeDefinitionNodes; - - public OpenAPIComponentMapper(Components components, NonTerminalNode rootNode) { + public OpenAPIComponentMapper(Components components, ModuleMemberVisitor moduleMemberVisitor) { this.components = components; - this.rootNode = rootNode; this.diagnostics = new ArrayList<>(); + this.typeDefinitionNodes = moduleMemberVisitor.getTypeDefinitionNodes(); } public List getDiagnostics() { @@ -122,24 +123,22 @@ public void createComponentSchema(Map schema, TypeSymbol typeSym } TypeReferenceTypeSymbol typeRef = (TypeReferenceTypeSymbol) typeSymbol; TypeSymbol type = typeRef.typeDescriptor(); - // Handle record type request body if (type.typeKind() == TypeDescKind.INTERSECTION) { type = excludeReadonlyIfPresent(type); } //Access module part node for finding the node to given typeSymbol. - //TODO: this works for module reference. - ModulePartNode modulePartNode = rootNode.syntaxTree().rootNode(); - NonTerminalNode nonTerminalNode = modulePartNode.findNode(typeSymbol.getLocation().get().textRange()); ConstraintAnnotation.ConstraintAnnotationBuilder constraintBuilder = new ConstraintAnnotation.ConstraintAnnotationBuilder(); - if (nonTerminalNode instanceof TypeDefinitionNode) { - TypeDefinitionNode node = (TypeDefinitionNode) nonTerminalNode; - - if (node.metadata().isPresent()) { - extractedConstraintAnnotation(node.metadata().get(), constraintBuilder); + ((TypeReferenceTypeSymbol) typeSymbol).definition().getName().ifPresent(name -> { + for (TypeDefinitionNode typeDefinitionNode : typeDefinitionNodes) { + if (typeDefinitionNode.typeName().text().equals(name)) { + if (typeDefinitionNode.metadata().isPresent()) { + extractedConstraintAnnotation(typeDefinitionNode.metadata().get(), constraintBuilder); + } + } } - } + }); ConstraintAnnotation constraintAnnot = constraintBuilder.build(); switch (type.typeKind()) { @@ -366,23 +365,43 @@ private ObjectSchema generateObjectSchemaFromRecordFields(Map sc List required = new ArrayList<>(); componentSchema.setDescription(apiDocs.get(componentName)); Map schemaProperties = new LinkedHashMap<>(); + RecordTypeDescriptorNode record = null; + // Get the record type descriptor node from given record type symbol + for (TypeDefinitionNode typeDefinitionNode : typeDefinitionNodes) { + if (typeDefinitionNode.typeName().text().equals(componentName)) { + if (typeDefinitionNode.typeDescriptor().kind().equals(SyntaxKind.RECORD_TYPE_DESC)) { + record = (RecordTypeDescriptorNode) typeDefinitionNode.typeDescriptor(); + } else if (typeDefinitionNode.typeDescriptor().kind().equals(SyntaxKind.INTERSECTION_TYPE_DESC)) { + IntersectionTypeDescriptorNode intersecNode = + (IntersectionTypeDescriptorNode) typeDefinitionNode.typeDescriptor(); + Node leftTypeDesc = intersecNode.leftTypeDesc(); + Node rightTypeDesc = intersecNode.rightTypeDesc(); + if (leftTypeDesc.kind().equals(SyntaxKind.RECORD_TYPE_DESC)) { + record = (RecordTypeDescriptorNode) leftTypeDesc; + } + if (rightTypeDesc.kind().equals(SyntaxKind.RECORD_TYPE_DESC)) { + record = (RecordTypeDescriptorNode) rightTypeDesc; + } + } + } + } + for (Map.Entry field : rfields.entrySet()) { ConstraintAnnotation.ConstraintAnnotationBuilder constraintBuilder = new ConstraintAnnotation.ConstraintAnnotationBuilder(); - - if (!(rootNode instanceof QualifiedNameReferenceNode)) { - ModulePartNode modulePartNode = rootNode.syntaxTree().rootNode(); - NonTerminalNode node = modulePartNode.findNode(field.getValue().getLocation().get().textRange()); - if (node instanceof RecordFieldNode) { - RecordFieldNode fieldNode = (RecordFieldNode) modulePartNode. - findNode(field.getValue().getLocation().get().textRange()); - Optional metadata = fieldNode.metadata(); - metadata.ifPresent(metadataNode -> extractedConstraintAnnotation(metadataNode, constraintBuilder)); + if (record != null) { + for (Node node : record.fields()) { + if (node instanceof RecordFieldNode) { + RecordFieldNode fieldNode = (RecordFieldNode) node; + if (fieldNode.fieldName().toString().equals(field.getKey())) { + Optional metadata = fieldNode.metadata(); + metadata.ifPresent(metadataNode -> extractedConstraintAnnotation(metadataNode, + constraintBuilder)); + } + } } } - ConstraintAnnotation constraintAnnot = constraintBuilder.build(); - String fieldName = ConverterCommonUtils.unescapeIdentifier(field.getKey().trim()); if (!field.getValue().isOptional()) { required.add(fieldName); diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIHeaderMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIHeaderMapper.java index 70466d441..054859d71 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIHeaderMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIHeaderMapper.java @@ -59,11 +59,14 @@ public class OpenAPIHeaderMapper { private final Components components; private final SemanticModel semanticModel; private final Map apidocs; + private final ModuleMemberVisitor moduleMemberVisitor; - public OpenAPIHeaderMapper(Components components, SemanticModel semanticModel, Map apidocs) { + public OpenAPIHeaderMapper(Components components, SemanticModel semanticModel, Map apidocs, + ModuleMemberVisitor moduleMemberVisitor) { this.apidocs = apidocs; this.components = components; this.semanticModel = semanticModel; + this.moduleMemberVisitor = moduleMemberVisitor; } /** @@ -86,7 +89,7 @@ public List setHeaderParameter(RequiredParameterNode headerParam) { if (headerDetailNode.kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) { SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) headerDetailNode; - headerTypeSchema = handleReference(semanticModel, components, refNode); + headerTypeSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor); } else { headerTypeSchema = ConverterCommonUtils.getOpenApiSchema(getHeaderType(headerParam)); } @@ -126,7 +129,7 @@ public List setHeaderParameter(DefaultableParameterNode headerParam) Schema headerTypeSchema; if (headerParam.typeName().kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) { SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) headerParam.typeName(); - headerTypeSchema = handleReference(semanticModel, components, refNode); + headerTypeSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor); } else { headerTypeSchema = ConverterCommonUtils.getOpenApiSchema(getHeaderType(headerParam)); } @@ -184,7 +187,7 @@ private void completeHeaderParameter(List parameters, String headerNa Schema itemSchema; if (kind == SyntaxKind.SIMPLE_NAME_REFERENCE) { SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) arrayNode.memberTypeDesc(); - itemSchema = handleReference(semanticModel, components, refNode); + itemSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor); } else { itemSchema = ConverterCommonUtils.getOpenApiSchema(kind); } diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIParameterMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIParameterMapper.java index 6b137ea9b..cfb686174 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIParameterMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIParameterMapper.java @@ -58,6 +58,7 @@ import static io.ballerina.openapi.converter.Constants.WILD_CARD_CONTENT_KEY; import static io.ballerina.openapi.converter.Constants.WILD_CARD_SUMMARY; import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.extractCustomMediaType; +import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.unescapeIdentifier; /** * OpenAPIParameterMapper provides functionality for converting ballerina parameter to OAS parameter model. @@ -69,6 +70,7 @@ public class OpenAPIParameterMapper { private final List errors = new ArrayList<>(); private final Components components; private final SemanticModel semanticModel; + private final ModuleMemberVisitor moduleMemberVisitor; public List getErrors() { return errors; @@ -76,13 +78,15 @@ public List getErrors() { public OpenAPIParameterMapper(FunctionDefinitionNode functionDefinitionNode, OperationAdaptor operationAdaptor, Map apidocs, - Components components, SemanticModel semanticModel) { + Components components, SemanticModel semanticModel, + ModuleMemberVisitor moduleMemberVisitor) { this.functionDefinitionNode = functionDefinitionNode; this.operationAdaptor = operationAdaptor; this.apidocs = apidocs; this.components = components; this.semanticModel = semanticModel; + this.moduleMemberVisitor = moduleMemberVisitor; } @@ -100,7 +104,7 @@ public void getResourceInputs(Components components, SemanticModel semanticModel SeparatedNodeList parameterList = functionSignature.parameters(); for (ParameterNode parameterNode : parameterList) { OpenAPIQueryParameterMapper queryParameterMapper = new OpenAPIQueryParameterMapper(apidocs, components, - semanticModel); + semanticModel, moduleMemberVisitor); if (parameterNode.kind() == SyntaxKind.REQUIRED_PARAM) { RequiredParameterNode requiredParameterNode = (RequiredParameterNode) parameterNode; // Handle query parameter @@ -159,11 +163,12 @@ private void createPathParameters(List parameters, NodeList pat ResourcePathParameterNode pathParam = (ResourcePathParameterNode) param; if (pathParam.typeDescriptor().kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) { SimpleNameReferenceNode queryNode = (SimpleNameReferenceNode) pathParam.typeDescriptor(); - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, pathParam); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, + moduleMemberVisitor); TypeSymbol typeSymbol = (TypeSymbol) semanticModel.symbol(queryNode).orElseThrow(); componentMapper.createComponentSchema(components.getSchemas(), typeSymbol); Schema schema = new Schema(); - schema.set$ref(ConverterCommonUtils.unescapeIdentifier(queryNode.name().text().trim())); + schema.set$ref(unescapeIdentifier(queryNode.name().text().trim())); pathParameterOAS.setSchema(schema); } else { pathParameterOAS.schema(ConverterCommonUtils.getOpenApiSchema( @@ -195,12 +200,13 @@ private void handleAnnotationParameters(Components components, for (AnnotationNode annotation: annotations) { if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_HEADER)) { // Handle headers. - OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs); + OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs, + moduleMemberVisitor); parameters.addAll(openAPIHeaderMapper.setHeaderParameter(requiredParameterNode)); } else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_QUERY)) { // Handle query parameter. OpenAPIQueryParameterMapper openAPIQueryParameterMapper = new OpenAPIQueryParameterMapper(apidocs, - components, semanticModel); + components, semanticModel, moduleMemberVisitor); parameters.add(openAPIQueryParameterMapper.createQueryParameter(requiredParameterNode)); } else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_PAYLOAD) && (!Constants.GET.toLowerCase(Locale.ENGLISH).equalsIgnoreCase( @@ -210,8 +216,9 @@ private void handleAnnotationParameters(Components components, Optional customMediaType = extractCustomMediaType(functionDefinitionNode); OpenAPIRequestBodyMapper openAPIRequestBodyMapper = customMediaType.map( value -> new OpenAPIRequestBodyMapper(components, - operationAdaptor, semanticModel, value)).orElse(new OpenAPIRequestBodyMapper(components, - operationAdaptor, semanticModel)); + operationAdaptor, semanticModel, value, moduleMemberVisitor)).orElse( + new OpenAPIRequestBodyMapper(components, + operationAdaptor, semanticModel, moduleMemberVisitor)); openAPIRequestBodyMapper.handlePayloadAnnotation(requiredParameterNode, schema, annotation, apidocs); errors.addAll(openAPIRequestBodyMapper.getDiagnostics()); } else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_PAYLOAD) && @@ -233,12 +240,13 @@ private List handleDefaultableAnnotationParameters(DefaultableParamet for (AnnotationNode annotation: annotations) { if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_HEADER)) { // Handle headers. - OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs); + OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs, + moduleMemberVisitor); parameters = openAPIHeaderMapper.setHeaderParameter(defaultableParameterNode); } else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_QUERY)) { // Handle query parameter. OpenAPIQueryParameterMapper openAPIQueryParameterMapper = new OpenAPIQueryParameterMapper(apidocs, - components, semanticModel); + components, semanticModel, moduleMemberVisitor); parameters.add(openAPIQueryParameterMapper.createQueryParameter(defaultableParameterNode)); } } diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIQueryParameterMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIQueryParameterMapper.java index 39275a4d9..b70abfec4 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIQueryParameterMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIQueryParameterMapper.java @@ -54,10 +54,10 @@ import static io.ballerina.compiler.syntax.tree.SyntaxKind.SIMPLE_NAME_REFERENCE; import static io.ballerina.compiler.syntax.tree.SyntaxKind.STRING_LITERAL; import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.getAnnotationNodesFromServiceNode; +import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.getOpenApiSchema; import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.handleReference; import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.unescapeIdentifier; - /** * This class processes mapping query parameters in between Ballerina and OAS. * @@ -67,14 +67,16 @@ public class OpenAPIQueryParameterMapper { private final Components components; private final SemanticModel semanticModel; private final Map apidocs; + private final ModuleMemberVisitor moduleMemberVisitor; private final SyntaxKind[] validExpressionKind = {STRING_LITERAL, NUMERIC_LITERAL, BOOLEAN_LITERAL, LIST_CONSTRUCTOR, NIL_LITERAL, MAPPING_CONSTRUCTOR}; public OpenAPIQueryParameterMapper(Map apidocs, Components components, - SemanticModel semanticModel) { + SemanticModel semanticModel, ModuleMemberVisitor moduleMemberVisitor) { this.apidocs = apidocs; this.components = components; this.semanticModel = semanticModel; + this.moduleMemberVisitor = moduleMemberVisitor; } /** @@ -87,7 +89,7 @@ public Parameter createQueryParameter(RequiredParameterNode queryParam) { if (queryParam.typeName() instanceof BuiltinSimpleNameReferenceNode && isQuery) { QueryParameter queryParameter = new QueryParameter(); queryParameter.setName(unescapeIdentifier(queryParamName)); - Schema openApiSchema = ConverterCommonUtils.getOpenApiSchema(queryParam.typeName().toString().trim()); + Schema openApiSchema = getOpenApiSchema(queryParam.typeName().toString().trim()); queryParameter.setSchema(openApiSchema); queryParameter.setRequired(true); if (!apidocs.isEmpty() && queryParam.paramName().isPresent() && apidocs.containsKey(queryParamName)) { @@ -115,7 +117,8 @@ public Parameter createQueryParameter(RequiredParameterNode queryParam) { QueryParameter queryParameter = new QueryParameter(); queryParameter.setName(unescapeIdentifier(queryParamName)); SimpleNameReferenceNode queryNode = (SimpleNameReferenceNode) queryParam.typeName(); - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, queryNode); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, moduleMemberVisitor); + TypeSymbol typeSymbol = (TypeSymbol) semanticModel.symbol(queryNode).orElseThrow(); componentMapper.createComponentSchema(components.getSchemas(), typeSymbol); Schema schema = new Schema<>(); @@ -129,7 +132,7 @@ public Parameter createQueryParameter(RequiredParameterNode queryParam) { } else if (queryParam.typeName().kind() == SIMPLE_NAME_REFERENCE) { QueryParameter queryParameter = new QueryParameter(); Schema refSchema = handleReference(semanticModel, components, (SimpleNameReferenceNode) - queryParam.typeName()); + queryParam.typeName(), moduleMemberVisitor); queryParameter.setSchema(refSchema); queryParameter.setRequired(true); if (!apidocs.isEmpty() && apidocs.containsKey(queryParamName)) { @@ -157,7 +160,7 @@ public Parameter createQueryParameter(DefaultableParameterNode defaultableQueryP QueryParameter queryParameter = new QueryParameter(); if (defaultableQueryParam.typeName() instanceof BuiltinSimpleNameReferenceNode && isQuery) { queryParameter.setName(unescapeIdentifier(queryParamName)); - Schema openApiSchema = ConverterCommonUtils.getOpenApiSchema( + Schema openApiSchema = getOpenApiSchema( defaultableQueryParam.typeName().toString().trim()); queryParameter.setSchema(openApiSchema); if (!apidocs.isEmpty() && defaultableQueryParam.paramName().isPresent() && @@ -176,7 +179,7 @@ public Parameter createQueryParameter(DefaultableParameterNode defaultableQueryP } else if (defaultableQueryParam.typeName().kind() == SIMPLE_NAME_REFERENCE) { queryParameter.setName(unescapeIdentifier(queryParamName)); Schema refSchema = handleReference(semanticModel, components, - (SimpleNameReferenceNode) defaultableQueryParam.typeName()); + (SimpleNameReferenceNode) defaultableQueryParam.typeName(), moduleMemberVisitor); queryParameter.setSchema(refSchema); queryParameter.setRequired(true); if (!apidocs.isEmpty() && apidocs.containsKey(queryParamName)) { @@ -224,13 +227,13 @@ private QueryParameter handleArrayTypeQueryParameter(String queryParamName, Arra TypeDescriptorNode itemTypeNode = arrayNode.memberTypeDesc(); Schema itemSchema; if (arrayNode.memberTypeDesc().kind() == OPTIONAL_TYPE_DESC) { - itemSchema = ConverterCommonUtils.getOpenApiSchema( + itemSchema = getOpenApiSchema( ((OptionalTypeDescriptorNode) itemTypeNode).typeDescriptor().toString().trim()); itemSchema.setNullable(true); } else if (arrayNode.memberTypeDesc().kind() == SIMPLE_NAME_REFERENCE) { itemSchema = getItemSchemaForReference(arrayNode); } else { - itemSchema = ConverterCommonUtils.getOpenApiSchema(itemTypeNode.toString().trim()); + itemSchema = getOpenApiSchema(itemTypeNode.toString().trim()); } arraySchema.setItems(itemSchema); queryParameter.schema(arraySchema); @@ -243,7 +246,7 @@ private QueryParameter handleArrayTypeQueryParameter(String queryParamName, Arra private Schema getItemSchemaForReference(ArrayTypeDescriptorNode arrayNode) { SimpleNameReferenceNode record = (SimpleNameReferenceNode) arrayNode.memberTypeDesc(); - return handleReference(semanticModel, components, record); + return handleReference(semanticModel, components, record, moduleMemberVisitor); } /** @@ -267,7 +270,7 @@ private QueryParameter setOptionalQueryParameter(String queryParamName, Optional if (arrayNode.memberTypeDesc().kind() == SIMPLE_NAME_REFERENCE) { itemSchema = getItemSchemaForReference(arrayNode); } else { - itemSchema = ConverterCommonUtils.getOpenApiSchema(itemTypeNode.toString().trim()); + itemSchema = getOpenApiSchema(itemTypeNode.toString().trim()); } arraySchema.setItems(itemSchema); queryParameter.schema(arraySchema); @@ -286,7 +289,8 @@ private QueryParameter setOptionalQueryParameter(String queryParamName, Optional } return queryParameter; } else if (node.kind() == SIMPLE_NAME_REFERENCE) { - Schema refSchema = handleReference(semanticModel, components, (SimpleNameReferenceNode) node); + Schema refSchema = handleReference(semanticModel, components, (SimpleNameReferenceNode) node, + moduleMemberVisitor); queryParameter.setSchema(refSchema); if (isOptional.equals(Constants.FALSE)) { queryParameter.setRequired(true); @@ -296,7 +300,7 @@ private QueryParameter setOptionalQueryParameter(String queryParamName, Optional } return queryParameter; } else { - Schema openApiSchema = ConverterCommonUtils.getOpenApiSchema(node.toString().trim()); + Schema openApiSchema = getOpenApiSchema(node.toString().trim()); openApiSchema.setNullable(true); queryParameter.setSchema(openApiSchema); if (!apidocs.isEmpty() && apidocs.containsKey(queryParamName)) { diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIRequestBodyMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIRequestBodyMapper.java index 201e23879..2478629d7 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIRequestBodyMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIRequestBodyMapper.java @@ -26,7 +26,6 @@ import io.ballerina.compiler.syntax.tree.MappingConstructorExpressionNode; import io.ballerina.compiler.syntax.tree.MappingFieldNode; import io.ballerina.compiler.syntax.tree.Node; -import io.ballerina.compiler.syntax.tree.NonTerminalNode; import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; import io.ballerina.compiler.syntax.tree.RequiredParameterNode; import io.ballerina.compiler.syntax.tree.SeparatedNodeList; @@ -73,7 +72,7 @@ public class OpenAPIRequestBodyMapper { private final SemanticModel semanticModel; private final String customMediaType; private final List diagnostics; - private NonTerminalNode rootNode; + private final ModuleMemberVisitor moduleMemberVisitor; /** * This constructor uses to create OpenAPIRequestBodyMapper instance when customMedia type enable. @@ -84,12 +83,14 @@ public class OpenAPIRequestBodyMapper { * @param customMediaType - custom media type */ public OpenAPIRequestBodyMapper(Components components, OperationAdaptor operationAdaptor, - SemanticModel semanticModel, String customMediaType) { + SemanticModel semanticModel, String customMediaType, + ModuleMemberVisitor moduleMemberVisitor) { this.components = components; this.operationAdaptor = operationAdaptor; this.semanticModel = semanticModel; this.customMediaType = customMediaType; this.diagnostics = new ArrayList<>(); + this.moduleMemberVisitor = moduleMemberVisitor; } /** @@ -100,8 +101,8 @@ public OpenAPIRequestBodyMapper(Components components, OperationAdaptor operatio * @param semanticModel - Semantic model for given ballerina service */ public OpenAPIRequestBodyMapper(Components components, OperationAdaptor operationAdaptor, - SemanticModel semanticModel) { - this(components, operationAdaptor, semanticModel, null); + SemanticModel semanticModel, ModuleMemberVisitor moduleMemberVisitor) { + this(components, operationAdaptor, semanticModel, null, moduleMemberVisitor); } public List getDiagnostics() { @@ -117,7 +118,6 @@ public List getDiagnostics() { */ public void handlePayloadAnnotation(RequiredParameterNode payloadNode, Map schema, AnnotationNode annotation, Map apiDocs) { - rootNode = payloadNode; if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_PAYLOAD)) { // Creating request body - required. RequestBody bodyParameter = new RequestBody(); @@ -230,7 +230,7 @@ private void handleArrayTypePayload(Map schema, ArrayTypeDescrip //handle record for components SimpleNameReferenceNode referenceNode = (SimpleNameReferenceNode) typeDescriptorNode; TypeSymbol typeSymbol = getReferenceTypeSymbol(semanticModel.symbol(referenceNode)); - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, referenceNode); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, moduleMemberVisitor); componentMapper.createComponentSchema(schema, typeSymbol); diagnostics.addAll(componentMapper.getDiagnostics()); Schema itemSchema = new Schema(); @@ -285,7 +285,7 @@ private void createRequestBody(RequestBody bodyParameter, RequiredParameterNode private void handleReferencePayload(TypeSymbol typeSymbol, String recordName, Map schema, String mediaType, RequestBody bodyParameter) { //handle record for components - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, rootNode); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, moduleMemberVisitor); componentMapper.createComponentSchema(schema, typeSymbol); diagnostics.addAll(componentMapper.getDiagnostics()); io.swagger.v3.oas.models.media.MediaType media = new io.swagger.v3.oas.models.media.MediaType(); diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResourceMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResourceMapper.java index ae33ba95a..8153cb89a 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResourceMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResourceMapper.java @@ -58,6 +58,7 @@ */ public class OpenAPIResourceMapper { private final SemanticModel semanticModel; + private final ModuleMemberVisitor moduleMemberVisitor; private final Paths pathObject = new Paths(); private final Components components = new Components(); private final List errors; @@ -69,9 +70,10 @@ public List getErrors() { /** * Initializes a resource parser for openApi. */ - OpenAPIResourceMapper(SemanticModel semanticModel) { + OpenAPIResourceMapper(SemanticModel semanticModel, ModuleMemberVisitor moduleMemberVisitor) { this.semanticModel = semanticModel; this.errors = new ArrayList<>(); + this.moduleMemberVisitor = moduleMemberVisitor; } public Components getComponents() { @@ -211,7 +213,7 @@ private Optional convertResourceToOperation(FunctionDefinition Map apiDocs = listAPIDocumentations(resource, op); //Add path parameters if in path and query parameters OpenAPIParameterMapper openAPIParameterMapper = new OpenAPIParameterMapper(resource, op, apiDocs, components, - semanticModel); + semanticModel, moduleMemberVisitor); openAPIParameterMapper.getResourceInputs(components, semanticModel); if (openAPIParameterMapper.getErrors().size() > 1 || (openAPIParameterMapper.getErrors().size() == 1 && !openAPIParameterMapper.getErrors().get(0).getCode().equals("OAS_CONVERTOR_113"))) { @@ -221,7 +223,7 @@ private Optional convertResourceToOperation(FunctionDefinition errors.addAll(openAPIParameterMapper.getErrors()); OpenAPIResponseMapper openAPIResponseMapper = new OpenAPIResponseMapper(semanticModel, components, - resource.location()); + resource.location(), moduleMemberVisitor); openAPIResponseMapper.getResourceOutput(resource, op); if (!openAPIResponseMapper.getErrors().isEmpty()) { errors.addAll(openAPIResponseMapper.getErrors()); diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResponseMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResponseMapper.java index 9fdc895e4..d8bf22c53 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResponseMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIResponseMapper.java @@ -152,15 +152,18 @@ public class OpenAPIResponseMapper { private final List errors = new ArrayList<>(); private final Location location; private String httpMethod; + private ModuleMemberVisitor moduleMemberVisitor; public List getErrors() { return errors; } - public OpenAPIResponseMapper(SemanticModel semanticModel, Components components, Location location) { + public OpenAPIResponseMapper(SemanticModel semanticModel, Components components, Location location, + ModuleMemberVisitor moduleMemberVisitor) { this.semanticModel = semanticModel; this.components = components; this.location = location; + this.moduleMemberVisitor = moduleMemberVisitor; } /** @@ -585,7 +588,7 @@ private Optional handleQualifiedNameType(ApiResponses apiResponses if (typeSymbol.typeKind() == TypeDescKind.RECORD) { ApiResponses responses = handleRecordTypeSymbol(qNode.identifier().text().trim(), components.getSchemas(), customMediaPrefix, typeRef, - new OpenAPIComponentMapper(components, qNode), + new OpenAPIComponentMapper(components, moduleMemberVisitor), headers); apiResponses.putAll(responses); return Optional.of(apiResponses); @@ -882,7 +885,7 @@ private void handleReferenceResponse(OperationAdaptor operationAdaptor, SimpleNa Optional symbol = semanticModel.symbol(referenceNode); TypeSymbol typeSymbol = (TypeSymbol) symbol.orElseThrow(); //handle record for components - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, referenceNode); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, moduleMemberVisitor); String mediaTypeString; // Check typeInclusion is related to the http status code if (referenceNode.parent().kind().equals(ARRAY_TYPE_DESC)) { diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIServiceMapper.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIServiceMapper.java index a7fc0d9aa..a7d7cbf62 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIServiceMapper.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/service/OpenAPIServiceMapper.java @@ -39,6 +39,7 @@ */ public class OpenAPIServiceMapper { private final SemanticModel semanticModel; + private final ModuleMemberVisitor moduleMemberVisitor; private final List errors = new ArrayList<>(); public List getErrors() { @@ -48,9 +49,10 @@ public List getErrors() { /** * Initializes a service parser for OpenApi. */ - public OpenAPIServiceMapper(SemanticModel semanticModel) { + public OpenAPIServiceMapper(SemanticModel semanticModel, ModuleMemberVisitor moduleMemberVisitor) { // Default object mapper is JSON mapper available in openApi utils. this.semanticModel = semanticModel; + this.moduleMemberVisitor = moduleMemberVisitor; } /** @@ -69,7 +71,7 @@ public OpenAPI convertServiceToOpenAPI(ServiceDeclarationNode service, OpenAPI o resource.add((FunctionDefinitionNode) function); } } - OpenAPIResourceMapper resourceMapper = new OpenAPIResourceMapper(this.semanticModel); + OpenAPIResourceMapper resourceMapper = new OpenAPIResourceMapper(this.semanticModel, this.moduleMemberVisitor); openapi.setPaths(resourceMapper.getPaths(resource)); openapi.setComponents(resourceMapper.getComponents()); errors.addAll(resourceMapper.getErrors()); diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ConverterCommonUtils.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ConverterCommonUtils.java index c9f9b032f..3e5a74836 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ConverterCommonUtils.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ConverterCommonUtils.java @@ -52,6 +52,7 @@ import io.ballerina.openapi.converter.diagnostic.ExceptionDiagnostic; import io.ballerina.openapi.converter.diagnostic.OpenAPIConverterDiagnostic; import io.ballerina.openapi.converter.model.OASResult; +import io.ballerina.openapi.converter.service.ModuleMemberVisitor; import io.ballerina.openapi.converter.service.OpenAPIComponentMapper; import io.ballerina.runtime.api.utils.IdentifierUtils; import io.ballerina.tools.diagnostics.Diagnostic; @@ -527,13 +528,13 @@ public static String unescapeIdentifier(String parameterName) { } public static Schema handleReference(SemanticModel semanticModel, Components components, - SimpleNameReferenceNode record) { + SimpleNameReferenceNode record, ModuleMemberVisitor moduleMemberVisitor) { Schema refSchema = new Schema<>(); // Creating request body - required. Optional symbol = semanticModel.symbol(record); if (symbol.isPresent() && symbol.get() instanceof TypeSymbol) { String recordName = record.name().toString().trim(); - OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components); + OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, moduleMemberVisitor); componentMapper.createComponentSchema(components.getSchemas(), (TypeSymbol) symbol.get()); refSchema.set$ref(ConverterCommonUtils.unescapeIdentifier(recordName)); } diff --git a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ServiceToOpenAPIConverterUtils.java b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ServiceToOpenAPIConverterUtils.java index 47bbf5768..77c9a0bf9 100644 --- a/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ServiceToOpenAPIConverterUtils.java +++ b/openapi-bal-service/src/main/java/io/ballerina/openapi/converter/utils/ServiceToOpenAPIConverterUtils.java @@ -203,7 +203,8 @@ private static void extractServiceNodes(String serviceName, List availab */ public static OASResult generateOAS(OASGenerationMetaInfo oasGenerationMetaInfo) { ServiceDeclarationNode serviceDefinition = oasGenerationMetaInfo.getServiceDeclarationNode(); - LinkedHashSet listeners = collectListeners(oasGenerationMetaInfo.getProject());; + ModuleMemberVisitor moduleMemberVisitor = extractNodesFromProject(oasGenerationMetaInfo.getProject()); + LinkedHashSet listeners = moduleMemberVisitor.getListenerDeclarationNodes(); SemanticModel semanticModel = oasGenerationMetaInfo.getSemanticModel(); String openApiFileName = oasGenerationMetaInfo.getOpenApiFileName(); Path ballerinaFilePath = oasGenerationMetaInfo.getBallerinaFilePath(); @@ -214,7 +215,8 @@ public static OASResult generateOAS(OASGenerationMetaInfo oasGenerationMetaInfo) OpenAPI openapi = oasResult.getOpenAPI().get(); if (openapi.getPaths() == null) { // Take base path of service - OpenAPIServiceMapper openAPIServiceMapper = new OpenAPIServiceMapper(semanticModel); + OpenAPIServiceMapper openAPIServiceMapper = new OpenAPIServiceMapper(semanticModel, + moduleMemberVisitor); // 02. Filter and set the ServerURLs according to endpoints. Complete the server section in OAS openapi = OpenAPIEndpointMapper.ENDPOINT_MAPPER.getServers(openapi, listeners, serviceDefinition); // 03. Filter path and component sections in OAS. @@ -489,17 +491,15 @@ private static OASResult resolveContractPath(List di * * @param project - current project */ - public static LinkedHashSet collectListeners(Project project) { + public static ModuleMemberVisitor extractNodesFromProject(Project project) { ModuleMemberVisitor balNodeVisitor = new ModuleMemberVisitor(); - LinkedHashSet listeners = new LinkedHashSet<>(); project.currentPackage().moduleIds().forEach(moduleId -> { Module module = project.currentPackage().module(moduleId); module.documentIds().forEach(documentId -> { SyntaxTree syntaxTreeDoc = module.document(documentId).syntaxTree(); syntaxTreeDoc.rootNode().accept(balNodeVisitor); - listeners.addAll(balNodeVisitor.getListenerDeclarationNodes()); }); }); - return listeners; + return balNodeVisitor; } } diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ConstraintTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ConstraintTests.java index 874b0f3eb..6da34aee4 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ConstraintTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ConstraintTests.java @@ -1,19 +1,19 @@ /* - * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com). * - * WSO2 Inc. licenses this file to you 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 + * WSO2 LLC. licenses this file to you 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 + * 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. + * 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.ballerina.openapi.generators.openapi; diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ModuleReferenceTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ModuleReferenceTests.java index ede75ddcc..91b299a12 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ModuleReferenceTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/openapi/ModuleReferenceTests.java @@ -73,7 +73,7 @@ public void testRecordReferenceWithReadOnly() throws IOException { TestUtils.compareWithGeneratedFile(ballerinaFilePath, "readonly.yaml"); } - @Test (enabled = false) + @Test () public void testListenersInSeparateModule() throws IOException { Path ballerinaFilePath = RES_DIR.resolve("listeners_in_separate_module.bal"); String osName = System.getProperty("os.name"); @@ -82,7 +82,7 @@ public void testListenersInSeparateModule() throws IOException { TestUtils.compareWithGeneratedFile(ballerinaFilePath, yamlFile); } - @Test (enabled = false) + @Test () public void testListenersInSeparateFiles() throws IOException { Path ballerinaFilePath = RES_DIR.resolve("listeners_in_separate_file.bal"); String osName = System.getProperty("os.name"); diff --git a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/arrayTypeResponse.yaml b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/arrayTypeResponse.yaml index fbbb9956a..f0df4278f 100644 --- a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/arrayTypeResponse.yaml +++ b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/arrayTypeResponse.yaml @@ -51,6 +51,7 @@ components: id: type: string name: + maxLength: 14 type: string description: type: string diff --git a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/array.yaml b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/array.yaml index b9b20e03b..25987bcad 100644 --- a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/array.yaml +++ b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/array.yaml @@ -20,22 +20,44 @@ paths: $ref: '#/components/schemas/Person' responses: "500": - description: Found unexpected output + description: Internal server error content: - text/plain: + application/json: schema: - type: string + $ref: '#/components/schemas/ErrorPayload' components: schemas: PersonDetailsItemsString: minLength: 7 type: string + ErrorPayload: + type: object + properties: + reason: + type: string + description: Reason phrase + path: + type: string + description: Request path + method: + type: string + description: Method type of the request + message: + type: string + description: Error message + timestamp: + type: string + description: Timestamp of the error + status: + type: integer + description: Relevant HTTP status code + format: int32 PersonFeeItemsNumber: maximum: 445.4 type: number format: float PersonLimitItemsInteger: - maximum: 67 + maximum: 67.0 type: integer format: int32 Hobby: diff --git a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/record_field.yaml b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/record_field.yaml index 25ffb4b6e..64786f551 100644 --- a/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/record_field.yaml +++ b/openapi-cli/src/test/resources/ballerina-to-openapi/expected_gen/constraint/record_field.yaml @@ -20,13 +20,35 @@ paths: $ref: '#/components/schemas/Person' responses: "500": - description: Found unexpected output + description: Internal server error content: - text/plain: + application/json: schema: - type: string + $ref: '#/components/schemas/ErrorPayload' components: schemas: + ErrorPayload: + type: object + properties: + reason: + type: string + description: Reason phrase + path: + type: string + description: Request path + method: + type: string + description: Method type of the request + message: + type: string + description: Error message + timestamp: + type: string + description: Timestamp of the error + status: + type: integer + description: Relevant HTTP status code + format: int32 Address: minLength: 5 type: string