Skip to content

Commit 40d5a74

Browse files
authored
364 asyncapi error interpreting projectbasedir in filepath (#365)
1 parent 5e56bca commit 40d5a74

77 files changed

Lines changed: 2934 additions & 2476 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/gradle-pr.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ jobs:
1616
id: get-version
1717
run: |
1818
cd scs-multiapi-gradle-plugin
19-
echo "version=$(gradle properties -q | grep "version:" | awk '{print $2}')" | tee $GITHUB_OUTPUT
19+
# Usar el wrapper para asegurar la versión de Gradle configurada en gradle-wrapper.properties
20+
# Ejecutar con flags para salida determinista
21+
version=$(./gradlew --no-daemon --console=plain properties -q | grep "version:" | awk '{print $2}')
22+
echo "version=$version" | tee $GITHUB_OUTPUT
2023
- name: Check if plugin version has been published
2124
uses: lakuapik/gh-actions-http-status@v1
2225
id: plugin-version-check

.github/workflows/maven-pr.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ jobs:
4343
runs-on: ubuntu-latest
4444
steps:
4545
- uses: actions/checkout@v4
46-
- name: Set up JDK 17
46+
- name: Set up JDK 21
4747
uses: actions/setup-java@v2
4848
with:
49-
java-version: "17"
49+
java-version: "21"
5050
distribution: "adopt"
5151
- name: Cache Maven packages
5252
uses: actions/cache@v4

multiapi-engine/pom.xml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
<groupId>com.sngular</groupId>
66
<artifactId>multiapi-engine</artifactId>
7-
<version>6.2.1</version>
7+
<version>6.3.0</version>
88
<packaging>jar</packaging>
99

1010
<properties>
11-
<maven.compiler.source>17</maven.compiler.source>
12-
<maven.compiler.target>17</maven.compiler.target>
11+
<maven.compiler.source>21</maven.compiler.source>
12+
<maven.compiler.target>21</maven.compiler.target>
1313
<swagger-parser.version>2.1.12</swagger-parser.version>
14-
<commons-lang3.version>3.15.0</commons-lang3.version>
14+
<commons-lang3.version>3.17.0</commons-lang3.version>
1515
<commons-io.version>2.16.1</commons-io.version>
1616
<commons-collections4.version>4.4</commons-collections4.version>
1717
<jackson.version>2.17.2</jackson.version>
@@ -69,6 +69,7 @@
6969
<groupId>org.projectlombok</groupId>
7070
<artifactId>lombok</artifactId>
7171
<version>${lombok.version}</version>
72+
<scope>provided</scope>
7273
</dependency>
7374
<dependency>
7475
<groupId>org.slf4j</groupId>
@@ -209,10 +210,17 @@
209210
<artifactId>maven-compiler-plugin</artifactId>
210211
<version>3.14.0</version>
211212
<configuration>
212-
<source>${maven.compiler.target}</source>
213-
<target>${maven.compiler.target}</target>
213+
<!-- Usar release en lugar de source/target para fijar la API estándar del JDK -->
214+
<release>${maven.compiler.target}</release>
214215
<debug>true</debug>
215216
<debuglevel>lines,vars,source</debuglevel>
217+
<annotationProcessorPaths>
218+
<path>
219+
<groupId>org.projectlombok</groupId>
220+
<artifactId>lombok</artifactId>
221+
<version>${lombok.version}</version>
222+
</path>
223+
</annotationProcessorPaths>
216224
</configuration>
217225
</plugin>
218226
<plugin>

multiapi-engine/src/main/java/com/sngular/api/generator/plugin/PluginConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ public class PluginConstants {
1414

1515
public static final String GENERATED_SOURCES_API_GENERATOR_FOLDER = "apigenerator/";
1616

17-
private PluginConstants() {}
17+
private PluginConstants() {
18+
}
1819
}

multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/AsyncApiGenerator.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66

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

9+
import java.io.File;
10+
import java.io.FileInputStream;
11+
import java.io.FileNotFoundException;
12+
import java.io.IOException;
13+
import java.io.InputStream;
14+
import java.net.URI;
15+
import java.nio.file.Paths;
16+
import java.util.Collections;
17+
import java.util.List;
18+
import java.util.Objects;
19+
920
import com.fasterxml.jackson.databind.JsonNode;
1021
import com.fasterxml.jackson.databind.ObjectMapper;
1122
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
@@ -15,33 +26,34 @@
1526
import com.sngular.api.generator.plugin.common.files.ClasspathFileLocation;
1627
import com.sngular.api.generator.plugin.common.files.DirectoryFileLocation;
1728
import com.sngular.api.generator.plugin.common.files.FileLocation;
29+
import com.sngular.api.generator.plugin.common.tools.PathUtil;
1830
import lombok.extern.slf4j.Slf4j;
1931
import org.apache.commons.lang3.tuple.ImmutablePair;
2032
import org.apache.commons.lang3.tuple.Pair;
2133

22-
import java.io.*;
23-
import java.net.URI;
24-
import java.util.Collections;
25-
import java.util.List;
26-
import java.util.Objects;
27-
2834
@Slf4j
2935
public class AsyncApiGenerator {
3036

3137
private final Integer springBootVersion;
38+
3239
private final boolean overwriteModel;
40+
3341
private final File targetFolder;
42+
3443
private final String processedGeneratedSourcesFolder;
44+
3545
private final String groupId;
46+
3647
private final File baseDir;
3748

38-
public AsyncApiGenerator(final Integer springBootVersion,
39-
boolean overwriteModel,
40-
final File targetFolder,
41-
final String processedGeneratedSourcesFolder,
42-
final String groupId,
43-
final File baseDir) {
44-
log.debug("Initializing AsyncApiGenerator with Spring Boot version: {}", springBootVersion);
49+
public AsyncApiGenerator(
50+
final Integer springBootVersion,
51+
boolean overwriteModel,
52+
final File targetFolder,
53+
final String processedGeneratedSourcesFolder,
54+
final String groupId,
55+
final File baseDir) {
56+
log.debug("Initializing AsyncApiGenerator with Spring Boot version:{}", springBootVersion);
4557
this.springBootVersion = springBootVersion;
4658
this.overwriteModel = overwriteModel;
4759
this.targetFolder = targetFolder;
@@ -61,10 +73,8 @@ public final void processFileSpec(final List<SpecFile> specsListFile) {
6173
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
6274
final JsonNode openApi = mapper.readTree(ymlLocation.getKey());
6375
final String version = getAsyncApiVersion(openApi);
64-
6576
BaseAsyncApiHandler handler = AsyncApiHandlerFactory
66-
.getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);
67-
77+
.getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);
6878
handler.processFileSpec(Collections.singletonList(specFile));
6979
} catch (IOException e) {
7080
log.error("Error processing spec file: {}", specFile.getFilePath(), e);
@@ -74,10 +84,8 @@ public final void processFileSpec(final List<SpecFile> specsListFile) {
7484
}
7585

7686
private static Pair<InputStream, FileLocation> resolveYmlLocation(final String ymlFilePath) throws FileNotFoundException {
77-
log.debug("Resolving YAML file location: {}", ymlFilePath);
78-
87+
log.debug("Resolving YAML file location:{}", ymlFilePath);
7988
final InputStream classPathInput = AsyncApiGenerator.class.getClassLoader().getResourceAsStream(ymlFilePath);
80-
8189
final InputStream ymlFile;
8290
final FileLocation ymlParentPath;
8391
if (Objects.nonNull(classPathInput)) {
@@ -88,9 +96,13 @@ private static Pair<InputStream, FileLocation> resolveYmlLocation(final String y
8896
log.debug("Looking for file in filesystem");
8997
final File f = new File(ymlFilePath);
9098
ymlFile = new FileInputStream(f);
91-
ymlParentPath = new DirectoryFileLocation(f.toPath().getParent());
99+
// For absolute paths, use the parent directly; otherwise, resolve relative to current directory
100+
if (PathUtil.isAbsolutePath(ymlFilePath)) {
101+
ymlParentPath = new DirectoryFileLocation(Paths.get(ymlFilePath).getParent());
102+
} else {
103+
ymlParentPath = new DirectoryFileLocation(f.toPath().getParent());
104+
}
92105
}
93-
94106
return new ImmutablePair<>(ymlFile, ymlParentPath);
95107
}
96108

multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/exception/InvalidAvroException.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
package com.sngular.api.generator.plugin.asyncapi.exception;
88

99
public class InvalidAvroException extends RuntimeException {
10-
private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace.";
11-
public InvalidAvroException(final String enumName) {
12-
super(String.format(ERROR_MESSAGE, enumName));
13-
}
10+
11+
private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace.";
12+
13+
public InvalidAvroException(final String enumName) {
14+
super(String.format(ERROR_MESSAGE, enumName));
15+
}
1416
}

multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi2Handler.java

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
package com.sngular.api.generator.plugin.asyncapi.handler;
22

3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.URISyntaxException;
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.HashMap;
10+
import java.util.Iterator;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Map.Entry;
14+
import java.util.Objects;
15+
316
import com.fasterxml.jackson.databind.JsonNode;
417
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.sngular.api.generator.plugin.asyncapi.exception.*;
18+
import com.sngular.api.generator.plugin.asyncapi.exception.ChannelNameException;
19+
import com.sngular.api.generator.plugin.asyncapi.exception.DuplicatedOperationException;
20+
import com.sngular.api.generator.plugin.asyncapi.exception.ExternalRefComponentNotFoundException;
21+
import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException;
22+
import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAsyncAPIException;
23+
import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException;
624
import com.sngular.api.generator.plugin.asyncapi.model.ProcessBindingsResult;
725
import com.sngular.api.generator.plugin.asyncapi.model.ProcessMethodResult;
826
import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject;
@@ -20,21 +38,15 @@
2038
import org.apache.commons.lang3.StringUtils;
2139
import org.apache.commons.lang3.tuple.Pair;
2240

23-
import java.io.File;
24-
import java.io.IOException;
25-
import java.io.InputStream;
26-
import java.net.URISyntaxException;
27-
import java.util.*;
28-
import java.util.Map.Entry;
29-
3041
public class AsyncApi2Handler extends BaseAsyncApiHandler {
3142

32-
public AsyncApi2Handler(final Integer springBootVersion,
33-
boolean overwriteModel,
34-
final File targetFolder,
35-
final String processedGeneratedSourcesFolder,
36-
final String groupId,
37-
final File baseDir) {
43+
public AsyncApi2Handler(
44+
final Integer springBootVersion,
45+
boolean overwriteModel,
46+
final File targetFolder,
47+
final String processedGeneratedSourcesFolder,
48+
final String groupId,
49+
final File baseDir) {
3850
super(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir);
3951
}
4052

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

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

88100
ApiTool.getComponent(node, MESSAGES).forEachRemaining(
89101
message -> getMessageSchemas(message.getKey(), message.getValue(), ymlParent, totalSchemas)
90-
);
102+
);
91103

92104
getChannels(node).forEachRemaining(
93105
channel -> getChannelSchemas(channel.getValue(), totalSchemas, ymlParent)
94-
);
106+
);
95107

96108
return totalSchemas;
97109
}
@@ -132,7 +144,8 @@ protected void processSupplierMethod(
132144

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

155168
@Override
156-
protected void fillTemplateFactory(final String operationId,
169+
protected void fillTemplateFactory(
170+
final String operationId,
157171
final ProcessMethodResult processedMethod, final Map<String, JsonNode> totalSchemas, final OperationParameterObject operationObject)
158172
throws IOException {
159173
final String classFullName = processedMethod.getNamespace();
@@ -238,7 +252,7 @@ protected String processMessageRef(final JsonNode messageBody, final String mode
238252
if (messageContent.startsWith("#")) {
239253
namespace = processModelPackage(MapperUtil.getLongRefClass(messageBody), modelPackage);
240254
} else if (messageContent.contains("#") || StringUtils.endsWith(messageContent, "yml")
241-
|| StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) {
255+
|| StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) {
242256
namespace = processExternalRef(modelPackage, ymlParent, messageBody);
243257
} else {
244258
namespace = processExternalAvro(ymlParent, messageContent);
@@ -261,7 +275,9 @@ protected String processExternalAvro(final FileLocation ymlParent, final String
261275
final JsonNode fileTree = mapper.readTree(avroFile);
262276
final JsonNode avroNamespace = fileTree.get("namespace");
263277

264-
if (avroNamespace == null) throw new InvalidAvroException(avroFilePath);
278+
if (avroNamespace == null) {
279+
throw new InvalidAvroException(avroFilePath);
280+
}
265281

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

294310
@Override
295-
protected void processBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message,
311+
protected void processBindings(
312+
final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message,
296313
final CommonSpecFile commonSpecFile) {
297314
if (message.has(BINDINGS)) {
298315
final var bindingsNode = message.get(BINDINGS);
@@ -335,6 +352,27 @@ protected String processModelPackage(final String extractedPackage, final String
335352
return processedPackage;
336353
}
337354

355+
@Override
356+
protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) {
357+
return operation;
358+
}
359+
360+
@Override
361+
protected String getOperationId(final JsonNode channel) {
362+
final JsonNode channelDefinition = getChannelDefinition(channel);
363+
if (!channelDefinition.has(OPERATION_ID)) {
364+
throw new InvalidAsyncAPIException("Operation ID is required");
365+
}
366+
367+
final String operationId = channelDefinition.get(OPERATION_ID).asText();
368+
if (processedOperationIds.contains(operationId)) {
369+
throw new DuplicatedOperationException(operationId);
370+
}
371+
372+
processedOperationIds.add(operationId);
373+
return operationId;
374+
}
375+
338376
private Iterator<Entry<String, JsonNode>> getChannels(final JsonNode node) {
339377
return ApiTool.hasNode(node, CHANNELS) ? ApiTool.getNode(node, CHANNELS).fields() : Collections.emptyIterator();
340378
}
@@ -408,25 +446,4 @@ private JsonNode getChannelDefinition(final JsonNode channel) {
408446

409447
return channelDefinition;
410448
}
411-
412-
@Override
413-
protected String getOperationId(final JsonNode channel) {
414-
final JsonNode channelDefinition = getChannelDefinition(channel);
415-
if (!channelDefinition.has(OPERATION_ID)) {
416-
throw new InvalidAsyncAPIException("Operation ID is required");
417-
}
418-
419-
final String operationId = channelDefinition.get(OPERATION_ID).asText();
420-
if (processedOperationIds.contains(operationId)) {
421-
throw new DuplicatedOperationException(operationId);
422-
}
423-
424-
processedOperationIds.add(operationId);
425-
return operationId;
426-
}
427-
428-
@Override
429-
protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) {
430-
return operation;
431-
}
432449
}

0 commit comments

Comments
 (0)