Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/gradle-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ jobs:
id: get-version
run: |
cd scs-multiapi-gradle-plugin
echo "version=$(gradle properties -q | grep "version:" | awk '{print $2}')" | tee $GITHUB_OUTPUT
# Usar el wrapper para asegurar la versión de Gradle configurada en gradle-wrapper.properties
# Ejecutar con flags para salida determinista
version=$(./gradlew --no-daemon --console=plain properties -q | grep "version:" | awk '{print $2}')
echo "version=$version" | tee $GITHUB_OUTPUT
- name: Check if plugin version has been published
uses: lakuapik/gh-actions-http-status@v1
id: plugin-version-check
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maven-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v2
with:
java-version: "17"
java-version: "21"
distribution: "adopt"
- name: Cache Maven packages
uses: actions/cache@v4
Expand Down
20 changes: 14 additions & 6 deletions multiapi-engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

<groupId>com.sngular</groupId>
<artifactId>multiapi-engine</artifactId>
<version>6.2.1</version>
<version>6.3.0</version>
<packaging>jar</packaging>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<swagger-parser.version>2.1.12</swagger-parser.version>
<commons-lang3.version>3.15.0</commons-lang3.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<commons-io.version>2.16.1</commons-io.version>
<commons-collections4.version>4.4</commons-collections4.version>
<jackson.version>2.17.2</jackson.version>
Expand Down Expand Up @@ -69,6 +69,7 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down Expand Up @@ -209,10 +210,17 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<source>${maven.compiler.target}</source>
<target>${maven.compiler.target}</target>
<!-- Usar release en lugar de source/target para fijar la API estándar del JDK -->
<release>${maven.compiler.target}</release>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public class PluginConstants {

public static final String GENERATED_SOURCES_API_GENERATOR_FOLDER = "apigenerator/";

private PluginConstants() {}
private PluginConstants() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@

package com.sngular.api.generator.plugin.asyncapi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
Expand All @@ -15,33 +26,34 @@
import com.sngular.api.generator.plugin.common.files.ClasspathFileLocation;
import com.sngular.api.generator.plugin.common.files.DirectoryFileLocation;
import com.sngular.api.generator.plugin.common.files.FileLocation;
import com.sngular.api.generator.plugin.common.tools.PathUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import java.io.*;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Slf4j
public class AsyncApiGenerator {

private final Integer springBootVersion;

private final boolean overwriteModel;

private final File targetFolder;

private final String processedGeneratedSourcesFolder;

private final String groupId;

private final File baseDir;

public AsyncApiGenerator(final Integer springBootVersion,
boolean overwriteModel,
final File targetFolder,
final String processedGeneratedSourcesFolder,
final String groupId,
final File baseDir) {
log.debug("Initializing AsyncApiGenerator with Spring Boot version: {}", springBootVersion);
public AsyncApiGenerator(
final Integer springBootVersion,
boolean overwriteModel,
final File targetFolder,
final String processedGeneratedSourcesFolder,
final String groupId,
final File baseDir) {
log.debug("Initializing AsyncApiGenerator with Spring Boot version:{}", springBootVersion);
this.springBootVersion = springBootVersion;
this.overwriteModel = overwriteModel;
this.targetFolder = targetFolder;
Expand All @@ -61,10 +73,8 @@ public final void processFileSpec(final List<SpecFile> specsListFile) {
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
final JsonNode openApi = mapper.readTree(ymlLocation.getKey());
final String version = getAsyncApiVersion(openApi);

BaseAsyncApiHandler handler = AsyncApiHandlerFactory
.getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);

.getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);
handler.processFileSpec(Collections.singletonList(specFile));
} catch (IOException e) {
log.error("Error processing spec file: {}", specFile.getFilePath(), e);
Expand All @@ -74,10 +84,8 @@ public final void processFileSpec(final List<SpecFile> specsListFile) {
}

private static Pair<InputStream, FileLocation> resolveYmlLocation(final String ymlFilePath) throws FileNotFoundException {
log.debug("Resolving YAML file location: {}", ymlFilePath);

log.debug("Resolving YAML file location:{}", ymlFilePath);
final InputStream classPathInput = AsyncApiGenerator.class.getClassLoader().getResourceAsStream(ymlFilePath);

final InputStream ymlFile;
final FileLocation ymlParentPath;
if (Objects.nonNull(classPathInput)) {
Expand All @@ -88,9 +96,13 @@ private static Pair<InputStream, FileLocation> resolveYmlLocation(final String y
log.debug("Looking for file in filesystem");
final File f = new File(ymlFilePath);
ymlFile = new FileInputStream(f);
ymlParentPath = new DirectoryFileLocation(f.toPath().getParent());
// For absolute paths, use the parent directly; otherwise, resolve relative to current directory
if (PathUtil.isAbsolutePath(ymlFilePath)) {
ymlParentPath = new DirectoryFileLocation(Paths.get(ymlFilePath).getParent());
} else {
ymlParentPath = new DirectoryFileLocation(f.toPath().getParent());
}
}

return new ImmutablePair<>(ymlFile, ymlParentPath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
package com.sngular.api.generator.plugin.asyncapi.exception;

public class InvalidAvroException extends RuntimeException {
private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace.";
public InvalidAvroException(final String enumName) {
super(String.format(ERROR_MESSAGE, enumName));
}

private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace.";

public InvalidAvroException(final String enumName) {
super(String.format(ERROR_MESSAGE, enumName));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
package com.sngular.api.generator.plugin.asyncapi.handler;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sngular.api.generator.plugin.asyncapi.exception.*;
import com.sngular.api.generator.plugin.asyncapi.exception.ChannelNameException;
import com.sngular.api.generator.plugin.asyncapi.exception.DuplicatedOperationException;
import com.sngular.api.generator.plugin.asyncapi.exception.ExternalRefComponentNotFoundException;
import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException;
import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAsyncAPIException;
import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException;
import com.sngular.api.generator.plugin.asyncapi.model.ProcessBindingsResult;
import com.sngular.api.generator.plugin.asyncapi.model.ProcessMethodResult;
import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject;
Expand All @@ -20,21 +38,15 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.*;
import java.util.Map.Entry;

public class AsyncApi2Handler extends BaseAsyncApiHandler {

public AsyncApi2Handler(final Integer springBootVersion,
boolean overwriteModel,
final File targetFolder,
final String processedGeneratedSourcesFolder,
final String groupId,
final File baseDir) {
public AsyncApi2Handler(
final Integer springBootVersion,
boolean overwriteModel,
final File targetFolder,
final String processedGeneratedSourcesFolder,
final String groupId,
final File baseDir) {
super(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);
}

Expand Down Expand Up @@ -83,15 +95,15 @@ protected Map<String, JsonNode> getAllSchemas(final FileLocation ymlParent, fina

ApiTool.getComponent(node, SCHEMAS).forEachRemaining(
schema -> totalSchemas.putIfAbsent(SCHEMAS.toUpperCase() + SLASH + MapperUtil.getSchemaKey(schema.getKey()), schema.getValue())
);
);

ApiTool.getComponent(node, MESSAGES).forEachRemaining(
message -> getMessageSchemas(message.getKey(), message.getValue(), ymlParent, totalSchemas)
);
);

getChannels(node).forEachRemaining(
channel -> getChannelSchemas(channel.getValue(), totalSchemas, ymlParent)
);
);

return totalSchemas;
}
Expand Down Expand Up @@ -132,7 +144,8 @@ protected void processSupplierMethod(

@Override
protected void processStreamBridgeMethod(
final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, final Map<String, JsonNode> totalSchemas)
final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName,
final Map<String, JsonNode> totalSchemas)
throws IOException {
final ProcessMethodResult result = processMethod(operationId, channel, operationObject, ymlParent, totalSchemas);
final String regex = "[a-zA-Z0-9.\\-]*";
Expand All @@ -153,7 +166,8 @@ protected void processSubscribeMethod(
}

@Override
protected void fillTemplateFactory(final String operationId,
protected void fillTemplateFactory(
final String operationId,
final ProcessMethodResult processedMethod, final Map<String, JsonNode> totalSchemas, final OperationParameterObject operationObject)
throws IOException {
final String classFullName = processedMethod.getNamespace();
Expand Down Expand Up @@ -238,7 +252,7 @@ protected String processMessageRef(final JsonNode messageBody, final String mode
if (messageContent.startsWith("#")) {
namespace = processModelPackage(MapperUtil.getLongRefClass(messageBody), modelPackage);
} else if (messageContent.contains("#") || StringUtils.endsWith(messageContent, "yml")
|| StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) {
|| StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) {
namespace = processExternalRef(modelPackage, ymlParent, messageBody);
} else {
namespace = processExternalAvro(ymlParent, messageContent);
Expand All @@ -261,7 +275,9 @@ protected String processExternalAvro(final FileLocation ymlParent, final String
final JsonNode fileTree = mapper.readTree(avroFile);
final JsonNode avroNamespace = fileTree.get("namespace");

if (avroNamespace == null) throw new InvalidAvroException(avroFilePath);
if (avroNamespace == null) {
throw new InvalidAvroException(avroFilePath);
}

namespace = avroNamespace.asText() + PACKAGE_SEPARATOR + fileTree.get("name").asText();
} catch (final IOException e) {
Expand Down Expand Up @@ -292,7 +308,8 @@ protected String processExternalRef(final String modelPackage, final FileLocatio
}

@Override
protected void processBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message,
protected void processBindings(
final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message,
final CommonSpecFile commonSpecFile) {
if (message.has(BINDINGS)) {
final var bindingsNode = message.get(BINDINGS);
Expand Down Expand Up @@ -335,6 +352,27 @@ protected String processModelPackage(final String extractedPackage, final String
return processedPackage;
}

@Override
protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) {
return operation;
}

@Override
protected String getOperationId(final JsonNode channel) {
final JsonNode channelDefinition = getChannelDefinition(channel);
if (!channelDefinition.has(OPERATION_ID)) {
throw new InvalidAsyncAPIException("Operation ID is required");
}

final String operationId = channelDefinition.get(OPERATION_ID).asText();
if (processedOperationIds.contains(operationId)) {
throw new DuplicatedOperationException(operationId);
}

processedOperationIds.add(operationId);
return operationId;
}

private Iterator<Entry<String, JsonNode>> getChannels(final JsonNode node) {
return ApiTool.hasNode(node, CHANNELS) ? ApiTool.getNode(node, CHANNELS).fields() : Collections.emptyIterator();
}
Expand Down Expand Up @@ -408,25 +446,4 @@ private JsonNode getChannelDefinition(final JsonNode channel) {

return channelDefinition;
}

@Override
protected String getOperationId(final JsonNode channel) {
final JsonNode channelDefinition = getChannelDefinition(channel);
if (!channelDefinition.has(OPERATION_ID)) {
throw new InvalidAsyncAPIException("Operation ID is required");
}

final String operationId = channelDefinition.get(OPERATION_ID).asText();
if (processedOperationIds.contains(operationId)) {
throw new DuplicatedOperationException(operationId);
}

processedOperationIds.add(operationId);
return operationId;
}

@Override
protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) {
return operation;
}
}
Loading
Loading