Commit baa8627
Feat/handle no payload (#687)
* feat(core): handle no payload methods
Co-authored-by: David Müller <[email protected]>
fix(core): extract AsyncMessage#description
Co-authored-by: David Müller <[email protected]>
feat(core): use fqn in for schema name
Co-authored-by: David Müller <[email protected]>
refactor(core): split test for PayloadClassExtractor and TypeToClassConverter
Co-authored-by: Timon Back <[email protected]>
test(kafka): remove unused use-fqn setting
Co-authored-by: David Müller <[email protected]>
test(kafka): update asyncapi.json
Co-authored-by: David Müller <[email protected]>
refactor(core): extract TypeToClassConverter
Co-authored-by: David Müller <[email protected]>
refactor(core): replace pair of resolved schema name and schema object with a specific record
Co-authored-by: Timon Back <[email protected]>
feat(core): add NoPayloadUsedConsumer
Co-authored-by: David Müller <[email protected]>
refactor(core): update AsyncHeadersBuilder (wip)
Co-authored-by: David Müller <[email protected]>
feat(core): Use new PayloadService (wip)
Co-authored-by: David Müller <[email protected]>
refactor(core): Check description in Schema annotation in DefaultComponentsService
test(core): Add PayloadServiceTest
refactor(core): Give PayloadService a name
feat(core): Add PayloadNotUsed Schema
Co-authored-by: Timon Back <[email protected]>
refactor(core): PayloadClassExtractor returns optional instead of throwing an exception
Co-authored-by: Timon Back <[email protected]>
diff --git a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessagePayload.java b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessagePayload.java
index 9ccf6e1c..e6302005 100644
--- a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessagePayload.java
+++ b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessagePayload.java
@@ -7,10 +7,12 @@ import io.github.springwolf.asyncapi.v3.model.schema.MultiFormatSchema;
import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.ToString;
@Getter
@JsonSerialize(using = MessagePayloadSerializer.class)
@EqualsAndHashCode
+@ToString
public class MessagePayload {
private MultiFormatSchema multiFormatSchema;
private SchemaObject schema;
diff --git a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessageReference.java b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessageReference.java
index b938b4d4..bc6b16b9 100644
--- a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessageReference.java
+++ b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/channel/message/MessageReference.java
@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
@EqualsAndHashCode
+@ToString
@NoArgsConstructor
@AllArgsConstructor
public class MessageReference implements Message, Reference {
diff --git a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaObject.java b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaObject.java
index 710a3ed0..497fb78e 100644
--- a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaObject.java
+++ b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaObject.java
@@ -10,6 +10,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
+import lombok.ToString;
import java.math.BigDecimal;
import java.util.List;
@@ -31,6 +32,7 @@ import java.util.Map;
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
+@ToString
public class SchemaObject extends ExtendableObject implements Schema {
/**
* Adds support for polymorphism. The discriminator is the schema property name that is used to differentiate
diff --git a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaReference.java b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaReference.java
index 2384a153..848c27fb 100644
--- a/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaReference.java
+++ b/springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model/schema/SchemaReference.java
@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
@EqualsAndHashCode
+@ToString
@NoArgsConstructor
@AllArgsConstructor
public class SchemaReference implements Schema, Reference {
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/ComponentsService.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/ComponentsService.java
index 9c982b3d..f5132257 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/ComponentsService.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/ComponentsService.java
@@ -12,6 +12,8 @@ public interface ComponentsService {
Map<String, SchemaObject> getSchemas();
+ SchemaObject resolveSchema(String schemaName);
+
String registerSchema(SchemaObject headers);
String registerSchema(Class<?> type);
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/DefaultComponentsService.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/DefaultComponentsService.java
index 59caf4e5..f2e3104c 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/DefaultComponentsService.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/DefaultComponentsService.java
@@ -14,6 +14,7 @@ import io.swagger.v3.core.jackson.TypeNameResolver;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
+import jakarta.annotation.Nullable;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -60,6 +61,15 @@ public class DefaultComponentsService implements ComponentsService {
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
+ @Override
+ @Nullable
+ public SchemaObject resolveSchema(String schemaName) {
+ if (schemas.containsKey(schemaName)) {
+ return swaggerSchemaUtil.mapSchema(schemas.get(schemaName));
+ }
+ return null;
+ }
+
@Override
public String registerSchema(SchemaObject headers) {
log.debug("Registering schema for {}", headers.getTitle());
@@ -81,6 +91,7 @@ public class DefaultComponentsService implements ComponentsService {
@Override
public String registerSchema(Class<?> type) {
+ // FIXME: Move this to the new HeadersService
return this.registerSchema(type, properties.getDocket().getDefaultContentType());
}
@@ -90,13 +101,13 @@ public class DefaultComponentsService implements ComponentsService {
String actualContentType =
StringUtils.isBlank(contentType) ? properties.getDocket().getDefaultContentType() : contentType;
- Map<String, Schema> schemas = new LinkedHashMap<>(runWithFqnSetting((unused) -> converter.readAll(type)));
+ Map<String, Schema> newSchemas = new LinkedHashMap<>(runWithFqnSetting((unused) -> converter.readAll(type)));
- String schemaName = getSchemaName(type, schemas);
+ String schemaName = getSchemaName(type, newSchemas);
- preProcessSchemas(schemas, schemaName, type);
- schemas.forEach(this.schemas::putIfAbsent);
- schemas.values().forEach(schema -> postProcessSchema(schema, actualContentType));
+ preProcessSchemas(newSchemas, schemaName, type);
+ newSchemas.forEach(this.schemas::putIfAbsent);
+ newSchemas.values().forEach(schema -> postProcessSchema(schema, actualContentType));
return schemaName;
}
@@ -130,11 +141,22 @@ public class DefaultComponentsService implements ComponentsService {
return new ArrayList<>(resolvedPayloadModelName).get(0);
}
- return type.getSimpleName();
+ return getNameFromClass(type);
}
private void preProcessSchemas(Map<String, Schema> schemas, String schemaName, Class<?> type) {
processAsyncApiPayloadAnnotation(schemas, schemaName, type);
+ processSchemaAnnotation(schemas, schemaName, type);
+ }
+
+ private void processSchemaAnnotation(Map<String, Schema> schemas, String schemaName, Class<?> type) {
+ Schema schemaForType = schemas.get(schemaName);
+ if (schemaForType != null) {
+ var schemaAnnotation = type.getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class);
+ if (schemaAnnotation != null) {
+ schemaForType.setDescription(schemaAnnotation.description());
+ }
+ }
}
private void processAsyncApiPayloadAnnotation(Map<String, Schema> schemas, String schemaName, Class<?> type) {
@@ -161,9 +183,9 @@ public class DefaultComponentsService implements ComponentsService {
}
private String registerString() {
- String schemaName = "String";
+ String schemaName = getNameFromClass(String.class);
StringSchema schema = new StringSchema();
- schema.setName(String.class.getName());
+ schema.setName(schemaName);
this.schemas.put(schemaName, schema);
postProcessSchema(schema, DEFAULT_CONTENT_TYPE);
@@ -181,6 +203,13 @@ public class DefaultComponentsService implements ComponentsService {
return result;
}
+ private String getNameFromClass(Class<?> type) {
+ if (properties.isUseFqn()) {
+ return type.getName();
+ }
+ return type.getSimpleName();
+ }
+
private void postProcessSchema(Schema schema, String contentType) {
for (SchemasPostProcessor processor : schemaPostProcessors) {
processor.process(schema, schemas, contentType);
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersBuilder.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersBuilder.java
index 195fcb13..0496125f 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersBuilder.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersBuilder.java
@@ -2,7 +2,8 @@
package io.github.springwolf.core.asyncapi.components.headers;
import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
public interface AsyncHeadersBuilder {
- SchemaObject buildHeaders(Class<?> payloadType);
+ SchemaObject buildHeaders(NamedSchemaObject payloadSchema);
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotDocumented.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotDocumented.java
index b1548c4e..77b177bf 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotDocumented.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotDocumented.java
@@ -2,6 +2,7 @@
package io.github.springwolf.core.asyncapi.components.headers;
import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
import java.util.List;
import java.util.Map;
@@ -22,7 +23,7 @@ public class AsyncHeadersNotDocumented implements AsyncHeadersBuilder {
}
@Override
- public SchemaObject buildHeaders(Class<?> payloadType) {
+ public SchemaObject buildHeaders(NamedSchemaObject payloadSchema) {
return NOT_DOCUMENTED;
}
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotUsed.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotUsed.java
index 19ffed26..8b026f07 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotUsed.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/headers/AsyncHeadersNotUsed.java
@@ -2,6 +2,7 @@
package io.github.springwolf.core.asyncapi.components.headers;
import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
import java.util.List;
import java.util.Map;
@@ -21,7 +22,7 @@ public class AsyncHeadersNotUsed implements AsyncHeadersBuilder {
}
@Override
- public SchemaObject buildHeaders(Class<?> payloadType) {
+ public SchemaObject buildHeaders(NamedSchemaObject payloadSchema) {
return NOT_USED;
}
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/AsyncAnnotationChannelsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/AsyncAnnotationChannelsScanner.java
index 253e1c7c..7c28ddab 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/AsyncAnnotationChannelsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/AsyncAnnotationChannelsScanner.java
@@ -15,6 +15,7 @@ import io.github.springwolf.core.asyncapi.scanners.bindings.operations.Operation
import io.github.springwolf.core.asyncapi.scanners.classes.ClassScanner;
import io.github.springwolf.core.asyncapi.scanners.common.AsyncAnnotationScanner;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AsyncAnnotationUtil;
import io.github.springwolf.core.configuration.docket.AsyncApiDocketService;
import lombok.extern.slf4j.Slf4j;
@@ -36,11 +37,13 @@ public class AsyncAnnotationChannelsScanner<A extends Annotation> extends AsyncA
ComponentsService componentsService,
AsyncApiDocketService asyncApiDocketService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
super(
asyncAnnotationProvider,
payloadClassExtractor,
+ payloadService,
componentsService,
operationBindingProcessors,
messageBindingProcessors);
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScanner.java
index d86fff29..22d88226 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScanner.java
@@ -8,7 +8,7 @@ import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
import io.github.springwolf.core.asyncapi.scanners.common.ClassLevelAnnotationScanner;
-import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import lombok.extern.slf4j.Slf4j;
@@ -30,14 +30,14 @@ public class SpringAnnotationClassLevelChannelsScanner<
Class<MethodAnnotation> methodAnnotationClass,
BindingFactory<ClassAnnotation> bindingFactory,
AsyncHeadersBuilder asyncHeadersBuilder,
- PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
ComponentsService componentsService) {
super(
classAnnotationClass,
methodAnnotationClass,
bindingFactory,
asyncHeadersBuilder,
- payloadClassExtractor,
+ payloadService,
componentsService);
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationMethodLevelChannelsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationMethodLevelChannelsScanner.java
index c2942147..2321fa21 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationMethodLevelChannelsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationMethodLevelChannelsScanner.java
@@ -9,7 +9,8 @@ import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
import io.github.springwolf.core.asyncapi.scanners.common.MethodLevelAnnotationScanner;
-import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import lombok.extern.slf4j.Slf4j;
@@ -25,17 +26,17 @@ public class SpringAnnotationMethodLevelChannelsScanner<MethodAnnotation extends
extends MethodLevelAnnotationScanner<MethodAnnotation> implements SpringAnnotationChannelsScannerDelegator {
private final Class<MethodAnnotation> methodAnnotationClass;
- private final PayloadClassExtractor payloadClassExtractor;
+ private final PayloadService payloadService;
public SpringAnnotationMethodLevelChannelsScanner(
Class<MethodAnnotation> methodAnnotationClass,
BindingFactory<MethodAnnotation> bindingFactory,
AsyncHeadersBuilder asyncHeadersBuilder,
- PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
ComponentsService componentsService) {
super(bindingFactory, asyncHeadersBuilder, componentsService);
this.methodAnnotationClass = methodAnnotationClass;
- this.payloadClassExtractor = payloadClassExtractor;
+ this.payloadService = payloadService;
}
@Override
@@ -56,16 +57,15 @@ public class SpringAnnotationMethodLevelChannelsScanner<MethodAnnotation extends
MethodAnnotation annotation = AnnotationScannerUtil.findAnnotationOrThrow(methodAnnotationClass, method);
+ NamedSchemaObject payloadSchema = payloadService.extractSchema(method);
+ ChannelObject channelItem = buildChannelItem(annotation, payloadSchema);
+
String channelName = bindingFactory.getChannelName(annotation);
- Class<?> payload = payloadClassExtractor.extractFrom(method);
-
- ChannelObject channelItem = buildChannelItem(annotation, payload);
-
return Map.entry(channelName, channelItem);
}
- private ChannelObject buildChannelItem(MethodAnnotation annotation, Class<?> payloadType) {
- MessageObject message = buildMessage(annotation, payloadType);
+ private ChannelObject buildChannelItem(MethodAnnotation annotation, NamedSchemaObject payloadSchema) {
+ MessageObject message = buildMessage(annotation, payloadSchema);
return buildChannelItem(annotation, message);
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/AsyncAnnotationScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/AsyncAnnotationScanner.java
index 0dbba50d..48884d26 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/AsyncAnnotationScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/AsyncAnnotationScanner.java
@@ -17,7 +17,9 @@ import io.github.springwolf.core.asyncapi.annotations.AsyncOperation;
import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.scanners.bindings.messages.MessageBindingProcessor;
import io.github.springwolf.core.asyncapi.scanners.bindings.operations.OperationBindingProcessor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AsyncAnnotationUtil;
import io.github.springwolf.core.asyncapi.scanners.common.utils.TextUtils;
@@ -42,6 +44,7 @@ public abstract class AsyncAnnotationScanner<A extends Annotation> implements Em
protected final AsyncAnnotationProvider<A> asyncAnnotationProvider;
protected final PayloadClassExtractor payloadClassExtractor;
+ protected final PayloadService payloadService;
protected final ComponentsService componentsService;
protected final List<OperationBindingProcessor> operationBindingProcessors;
protected final List<MessageBindingProcessor> messageBindingProcessors;
@@ -89,30 +92,33 @@ public abstract class AsyncAnnotationScanner<A extends Annotation> implements Em
}
protected MessageObject buildMessage(AsyncOperation operationData, Method method) {
- Class<?> payloadType = operationData.payloadType() != Object.class
- ? operationData.payloadType()
- : payloadClassExtractor.extractFrom(method);
+ NamedSchemaObject payloadSchema = payloadService.extractSchema(operationData, method);
- String modelName = this.componentsService.registerSchema(
- payloadType, operationData.message().contentType());
- SchemaObject asyncHeaders = AsyncAnnotationUtil.getAsyncHeaders(operationData, resolver);
- String headerModelName = this.componentsService.registerSchema(asyncHeaders);
- var headers = MessageHeaders.of(MessageReference.toSchema(headerModelName));
-
- var schema = payloadType.getAnnotation(Schema.class);
- String description = schema != null ? schema.description() : null;
+ // TODO: move block to own HeaderService
+ SchemaObject headerSchema = AsyncAnnotationUtil.getAsyncHeaders(operationData, resolver);
+ String headerSchemaName = this.componentsService.registerSchema(headerSchema);
+ var headers = MessageHeaders.of(MessageReference.toSchema(headerSchemaName));
Map<String, MessageBinding> messageBinding =
AsyncAnnotationUtil.processMessageBindingFromAnnotation(method, messageBindingProcessors);
var messagePayload = MessagePayload.of(MultiFormatSchema.builder()
- .schema(SchemaReference.fromSchema(modelName))
+ .schema(SchemaReference.fromSchema(payloadSchema.name()))
.build());
+ String description = operationData.message().description();
+ if (!StringUtils.hasText(description)) {
+ description = payloadSchema.schema().getDescription();
+ }
+ if (StringUtils.hasText(description)) {
+ description = this.resolver.resolveStringValue(description);
+ description = TextUtils.trimIndent(description);
+ }
+
var builder = MessageObject.builder()
- .messageId(payloadType.getName())
- .name(payloadType.getName())
- .title(payloadType.getSimpleName())
+ .messageId(payloadSchema.name())
+ .name(payloadSchema.name())
+ .title(payloadSchema.schema().getTitle())
.description(description)
.payload(messagePayload)
.headers(headers)
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/ClassLevelAnnotationScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/ClassLevelAnnotationScanner.java
index f814e939..8a7f6507 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/ClassLevelAnnotationScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/ClassLevelAnnotationScanner.java
@@ -11,7 +11,8 @@ import io.github.springwolf.asyncapi.v3.model.schema.SchemaReference;
import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
-import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import io.github.springwolf.core.asyncapi.scanners.operations.annotations.SpringAnnotationClassLevelOperationsScanner;
import lombok.RequiredArgsConstructor;
@@ -37,7 +38,7 @@ public abstract class ClassLevelAnnotationScanner<
protected final Class<MethodAnnotation> methodAnnotationClass;
protected final BindingFactory<ClassAnnotation> bindingFactory;
protected final AsyncHeadersBuilder asyncHeadersBuilder;
- protected final PayloadClassExtractor payloadClassExtractor;
+ protected final PayloadService payloadService;
protected final ComponentsService componentsService;
protected enum MessageType {
@@ -67,8 +68,8 @@ public abstract class ClassLevelAnnotationScanner<
SpringAnnotationClassLevelOperationsScanner.MessageType messageType) {
Set<MessageObject> messages = methods.stream()
.map((Method method) -> {
- Class<?> payloadType = payloadClassExtractor.extractFrom(method);
- return buildMessage(classAnnotation, payloadType);
+ NamedSchemaObject payloadSchema = payloadService.extractSchema(method);
+ return buildMessage(classAnnotation, payloadSchema);
})
.collect(toSet());
@@ -79,18 +80,19 @@ public abstract class ClassLevelAnnotationScanner<
return toMessagesMap(messages);
}
- protected MessageObject buildMessage(ClassAnnotation classAnnotation, Class<?> payloadType) {
+ protected MessageObject buildMessage(ClassAnnotation classAnnotation, NamedSchemaObject payloadSchema) {
Map<String, MessageBinding> messageBinding = bindingFactory.buildMessageBinding(classAnnotation);
- String modelName = componentsService.registerSchema(payloadType);
- String headerModelName = componentsService.registerSchema(asyncHeadersBuilder.buildHeaders(payloadType));
+
+ String headerModelName = componentsService.registerSchema(asyncHeadersBuilder.buildHeaders(payloadSchema));
+
MessagePayload payload = MessagePayload.of(MultiFormatSchema.builder()
- .schema(SchemaReference.fromSchema(modelName))
+ .schema(SchemaReference.fromSchema(payloadSchema.name()))
.build());
MessageObject message = MessageObject.builder()
- .messageId(payloadType.getName())
- .name(payloadType.getName())
- .title(payloadType.getSimpleName())
+ .messageId(payloadSchema.name())
+ .name(payloadSchema.name())
+ .title(payloadSchema.schema().getTitle())
.description(null)
.payload(payload)
.headers(MessageHeaders.of(MessageReference.toSchema(headerModelName)))
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/MethodLevelAnnotationScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/MethodLevelAnnotationScanner.java
index 1d548122..72f5e823 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/MethodLevelAnnotationScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/MethodLevelAnnotationScanner.java
@@ -11,6 +11,7 @@ import io.github.springwolf.asyncapi.v3.model.schema.SchemaReference;
import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -25,18 +26,20 @@ public abstract class MethodLevelAnnotationScanner<MethodAnnotation extends Anno
protected final AsyncHeadersBuilder asyncHeadersBuilder;
protected final ComponentsService componentsService;
- protected MessageObject buildMessage(MethodAnnotation annotation, Class<?> payloadType) {
+ protected MessageObject buildMessage(MethodAnnotation annotation, NamedSchemaObject payloadSchema) {
Map<String, MessageBinding> messageBinding = bindingFactory.buildMessageBinding(annotation);
- String modelName = componentsService.registerSchema(payloadType);
- String headerModelName = componentsService.registerSchema(asyncHeadersBuilder.buildHeaders(payloadType));
+
+ // TODO: move block to own HeaderService
+ String headerModelName = componentsService.registerSchema(asyncHeadersBuilder.buildHeaders(payloadSchema));
+
MessagePayload payload = MessagePayload.of(MultiFormatSchema.builder()
- .schema(SchemaReference.fromSchema(modelName))
+ .schema(SchemaReference.fromSchema(payloadSchema.name()))
.build());
MessageObject message = MessageObject.builder()
- .messageId(payloadType.getName())
- .name(payloadType.getName())
- .title(payloadType.getSimpleName())
+ .messageId(payloadSchema.name())
+ .name(payloadSchema.name())
+ .title(payloadSchema.schema().getTitle())
.description(null)
.payload(payload)
.headers(MessageHeaders.of(MessageReference.toSchema(headerModelName)))
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/NamedSchemaObject.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/NamedSchemaObject.java
new file mode 100644
index 00000000..9509becf
--- /dev/null
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/NamedSchemaObject.java
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: Apache-2.0
+package io.github.springwolf.core.asyncapi.scanners.common.payload;
+
+import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
+
+/**
+ * Encapsulates the resolved name for the contained schema.
+ * @param name The fully qualified name or the simple name of the schema.
+ * @param schema The SchemaObject.
+ */
+public record NamedSchemaObject(String name, SchemaObject schema) {}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadClassExtractor.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadClassExtractor.java
index 0d19c5e6..9e80ef74 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadClassExtractor.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadClassExtractor.java
@@ -1,52 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.springwolf.core.asyncapi.scanners.common.payload;
-import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.Payload;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import java.util.Arrays;
-import java.util.Map;
+import java.util.Optional;
+@RequiredArgsConstructor
@Slf4j
public class PayloadClassExtractor {
private final TypeToClassConverter typeToClassConverter;
- public PayloadClassExtractor(SpringwolfConfigProperties properties) {
- Map<String, Integer> extractableClasses = Map.of();
- if (properties.getPayload() != null) {
- extractableClasses = properties.getPayload().getExtractableClasses();
- }
- typeToClassConverter = new TypeToClassConverter(extractableClasses);
- }
-
- public Class<?> extractFrom(Method method) {
+ public Optional<Class<?>> extractFrom(Method method) {
String methodName = String.format("%s::%s", method.getDeclaringClass().getSimpleName(), method.getName());
log.debug("Finding payload type for {}", methodName);
- int parameterPayloadIndex =
- getPayloadParameterIndex(method.getParameterTypes(), method.getParameterAnnotations(), methodName);
-
- return typeToClassConverter.extractClass(method.getGenericParameterTypes()[parameterPayloadIndex]);
+ return getPayloadParameterIndex(method.getParameterTypes(), method.getParameterAnnotations(), methodName)
+ .map((parameterPayloadIndex) ->
+ typeToClassConverter.extractClass(method.getGenericParameterTypes()[parameterPayloadIndex]));
}
- public Class<?> typeToClass(Type type) {
- return typeToClassConverter.extractClass(type);
- }
-
- private int getPayloadParameterIndex(
+ private Optional<Integer> getPayloadParameterIndex(
Class<?>[] parameterClasses, Annotation[][] parameterAnnotations, String methodName) {
- switch (parameterClasses.length) {
- case 0 -> throw new IllegalArgumentException(
- "Payload cannot be detected. Method must not have 0 parameters: " + methodName);
- case 1 -> {
- return 0;
- }
+ return switch (parameterClasses.length) {
+ case 0 -> Optional.empty();
+ case 1 -> Optional.of(0);
default -> {
int payloadAnnotatedParameterIndex = getPayloadAnnotatedParameterIndex(parameterAnnotations);
if (payloadAnnotatedParameterIndex == -1) {
@@ -57,9 +39,9 @@ public class PayloadClassExtractor {
throw new IllegalArgumentException(msg);
}
- return payloadAnnotatedParameterIndex;
+ yield Optional.of(payloadAnnotatedParameterIndex);
}
- }
+ };
}
private int getPayloadAnnotatedParameterIndex(Annotation[][] parameterAnnotations) {
@@ -74,58 +56,4 @@ public class PayloadClassExtractor {
return -1;
}
-
- @RequiredArgsConstructor
- private static class TypeToClassConverter {
-
- private final Map<String, Integer> extractableClassToArgumentIndex;
-
- private Class<?> extractClass(Type parameterType) {
- try {
- if (parameterType instanceof ParameterizedType) {
- Type rawParameterType = ((ParameterizedType) parameterType).getRawType();
- String rawParameterTypeName = rawParameterType.getTypeName();
-
- Class<?> actualPayloadClass =
- extractActualGenericClass((ParameterizedType) parameterType, rawParameterTypeName);
- if (actualPayloadClass != Void.class) {
- return actualPayloadClass;
- }
-
- // nested generic class - fallback to most outer container
- return Class.forName(rawParameterTypeName);
- }
-
- // no generics used - just a normal type
- return Class.forName(parameterType.getTypeName());
- } catch (Exception ex) {
- log.info("Unable to extract generic data type of {}", parameterType, ex);
- }
- return Void.class;
- }
-
- private Class<?> extractActualGenericClass(ParameterizedType parameterType, String rawParameterTypeName) {
- Type type = parameterType;
- String typeName = rawParameterTypeName;
-
- while (type instanceof ParameterizedType && extractableClassToArgumentIndex.containsKey(typeName)) {
- Integer index = extractableClassToArgumentIndex.get(rawParameterTypeName);
-
- type = ((ParameterizedType) type).getActualTypeArguments()[index];
-
- typeName = type.getTypeName();
- if (type instanceof ParameterizedType) {
- typeName = ((ParameterizedType) type).getRawType().getTypeName();
- }
- }
-
- try {
- return Class.forName(typeName);
- } catch (ClassNotFoundException ex) {
- log.debug("Unable to find class for type {}", typeName, ex);
- }
-
- return Void.class;
- }
- }
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadService.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadService.java
new file mode 100644
index 00000000..69342a90
--- /dev/null
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/PayloadService.java
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: Apache-2.0
+package io.github.springwolf.core.asyncapi.scanners.common.payload;
+
+import io.github.springwolf.asyncapi.v3.model.schema.SchemaObject;
+import io.github.springwolf.core.asyncapi.annotations.AsyncOperation;
+import io.github.springwolf.core.asyncapi.components.ComponentsService;
+import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Optional;
+
+@Slf4j
+@RequiredArgsConstructor
+public class PayloadService {
+ private final PayloadClassExtractor payloadClassExtractor;
+ private final ComponentsService componentsService;
+ private final SpringwolfConfigProperties properties;
+
+ private static final String PAYLOAD_NOT_USED_KEY = "PayloadNotUsed";
+ static final NamedSchemaObject PAYLOAD_NOT_USED = new NamedSchemaObject(
+ PAYLOAD_NOT_USED_KEY,
+ SchemaObject.builder()
+ .title(PAYLOAD_NOT_USED_KEY)
+ .description("No payload specified")
+ .properties(Map.of())
+ .build());
+
+ public NamedSchemaObject extractSchema(Method method) {
+ Optional<Class<?>> payloadType = payloadClassExtractor.extractFrom(method);
+
+ String contentType = properties.getDocket().getDefaultContentType();
+ return payloadType.map((type) -> buildSchema(contentType, type)).orElseGet(this::useUnusedPayload);
+ }
+
+ public NamedSchemaObject extractSchema(AsyncOperation operationData, Method method) {
+ Optional<Class<?>> payloadType = operationData.payloadType() != Object.class
+ ? Optional.of(operationData.payloadType())
+ : payloadClassExtractor.extractFrom(method);
+
+ String contentType = operationData.message().contentType();
+ return payloadType.map((type) -> buildSchema(contentType, type)).orElseGet(this::useUnusedPayload);
+ }
+
+ private NamedSchemaObject buildSchema(String contentType, Class<?> payloadType) {
+ String componentsSchemaName = this.componentsService.registerSchema(payloadType, contentType);
+
+ SchemaObject schema = componentsService.resolveSchema(componentsSchemaName);
+ schema.setTitle(payloadType.getSimpleName());
+
+ return new NamedSchemaObject(componentsSchemaName, schema);
+ }
+
+ private NamedSchemaObject useUnusedPayload() {
+ this.componentsService.registerSchema(PAYLOAD_NOT_USED.schema());
+ return PAYLOAD_NOT_USED;
+ }
+}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/TypeToClassConverter.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/TypeToClassConverter.java
new file mode 100644
index 00000000..c55f8254
--- /dev/null
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/common/payload/TypeToClassConverter.java
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: Apache-2.0
+package io.github.springwolf.core.asyncapi.scanners.common.payload;
+
+import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+@Slf4j
+public class TypeToClassConverter {
+
+ private final Map<String, Integer> extractableClassToArgumentIndex;
+
+ public TypeToClassConverter(SpringwolfConfigProperties properties) {
+ if (properties.getPayload() != null) {
+ extractableClassToArgumentIndex = properties.getPayload().getExtractableClasses();
+ } else {
+ extractableClassToArgumentIndex = Map.of();
+ }
+ }
+
+ public Class<?> extractClass(Type parameterType) {
+ try {
+ if (parameterType instanceof ParameterizedType) {
+ Type rawParameterType = ((ParameterizedType) parameterType).getRawType();
+ String rawParameterTypeName = rawParameterType.getTypeName();
+
+ Class<?> actualPayloadClass =
+ extractActualGenericClass((ParameterizedType) parameterType, rawParameterTypeName);
+ if (actualPayloadClass != Void.class) {
+ return actualPayloadClass;
+ }
+
+ // nested generic class - fallback to most outer container
+ return Class.forName(rawParameterTypeName);
+ }
+
+ // no generics used - just a normal type
+ return Class.forName(parameterType.getTypeName());
+ } catch (Exception ex) {
+ log.info("Unable to extract generic data type of %s".formatted(parameterType), ex);
+ }
+ return Void.class;
+ }
+
+ private Class<?> extractActualGenericClass(ParameterizedType parameterType, String rawParameterTypeName) {
+ Type type = parameterType;
+ String typeName = rawParameterTypeName;
+
+ while (type instanceof ParameterizedType && extractableClassToArgumentIndex.containsKey(typeName)) {
+ Integer index = extractableClassToArgumentIndex.get(rawParameterTypeName);
+
+ type = ((ParameterizedType) type).getActualTypeArguments()[index];
+
+ typeName = type.getTypeName();
+ if (type instanceof ParameterizedType) {
+ typeName = ((ParameterizedType) type).getRawType().getTypeName();
+ }
+ }
+
+ try {
+ return Class.forName(typeName);
+ } catch (ClassNotFoundException ex) {
+ log.debug("Unable to find class for type %s".formatted(typeName), ex);
+ }
+
+ return Void.class;
+ }
+}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationOperationsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationOperationsScanner.java
index 6cee589b..16ac6204 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationOperationsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationOperationsScanner.java
@@ -10,6 +10,7 @@ import io.github.springwolf.core.asyncapi.scanners.bindings.operations.Operation
import io.github.springwolf.core.asyncapi.scanners.classes.ClassScanner;
import io.github.springwolf.core.asyncapi.scanners.common.AsyncAnnotationScanner;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.operations.OperationMerger;
import lombok.extern.slf4j.Slf4j;
@@ -28,11 +29,13 @@ public class AsyncAnnotationOperationsScanner<A extends Annotation> extends Asyn
ClassScanner classScanner,
ComponentsService componentsService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
super(
asyncAnnotationProvider,
payloadClassExtractor,
+ payloadService,
componentsService,
operationBindingProcessors,
messageBindingProcessors);
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationClassLevelOperationsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationClassLevelOperationsScanner.java
index 74b0db0c..81166950 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationClassLevelOperationsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationClassLevelOperationsScanner.java
@@ -10,7 +10,7 @@ import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
import io.github.springwolf.core.asyncapi.scanners.common.ClassLevelAnnotationScanner;
-import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import lombok.extern.slf4j.Slf4j;
@@ -32,14 +32,14 @@ public class SpringAnnotationClassLevelOperationsScanner<
Class<MethodAnnotation> methodAnnotationClass,
BindingFactory<ClassAnnotation> bindingFactory,
AsyncHeadersBuilder asyncHeadersBuilder,
- PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
ComponentsService componentsService) {
super(
classAnnotationClass,
methodAnnotationClass,
bindingFactory,
asyncHeadersBuilder,
- payloadClassExtractor,
+ payloadService,
componentsService);
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationMethodLevelOperationsScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationMethodLevelOperationsScanner.java
index e222893f..ac5448ac 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationMethodLevelOperationsScanner.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationMethodLevelOperationsScanner.java
@@ -11,7 +11,8 @@ import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersBuilder;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
import io.github.springwolf.core.asyncapi.scanners.common.MethodLevelAnnotationScanner;
-import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.NamedSchemaObject;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.common.utils.AnnotationScannerUtil;
import lombok.extern.slf4j.Slf4j;
@@ -28,17 +29,17 @@ public class SpringAnnotationMethodLevelOperationsScanner<MethodAnnotation exten
extends MethodLevelAnnotationScanner<MethodAnnotation> implements SpringAnnotationOperationsScannerDelegator {
private final Class<MethodAnnotation> methodAnnotationClass;
- private final PayloadClassExtractor payloadClassExtractor;
+ private final PayloadService payloadService;
public SpringAnnotationMethodLevelOperationsScanner(
Class<MethodAnnotation> methodAnnotationClass,
BindingFactory<MethodAnnotation> bindingFactory,
AsyncHeadersBuilder asyncHeadersBuilder,
- PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
ComponentsService componentsService) {
super(bindingFactory, asyncHeadersBuilder, componentsService);
this.methodAnnotationClass = methodAnnotationClass;
- this.payloadClassExtractor = payloadClassExtractor;
+ this.payloadService = payloadService;
}
@Override
@@ -61,13 +62,13 @@ public class SpringAnnotationMethodLevelOperationsScanner<MethodAnnotation exten
String channelName = bindingFactory.getChannelName(annotation);
String operationId = channelName + "_" + OperationAction.RECEIVE + "_" + method.getName();
- Class<?> payload = payloadClassExtractor.extractFrom(method);
+ NamedSchemaObject payloadSchema = payloadService.extractSchema(method);
- Operation operation = buildOperation(annotation, payload);
+ Operation operation = buildOperation(annotation, payloadSchema);
return Map.entry(operationId, operation);
}
- private Operation buildOperation(MethodAnnotation annotation, Class<?> payloadType) {
+ private Operation buildOperation(MethodAnnotation annotation, NamedSchemaObject payloadType) {
MessageObject message = buildMessage(annotation, payloadType);
return buildOperation(annotation, message);
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfAutoConfiguration.java b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfAutoConfiguration.java
index b8284b26..2851142c 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfAutoConfiguration.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfAutoConfiguration.java
@@ -28,6 +28,8 @@ import io.github.springwolf.core.asyncapi.operations.OperationsService;
import io.github.springwolf.core.asyncapi.scanners.ChannelsScanner;
import io.github.springwolf.core.asyncapi.scanners.OperationsScanner;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.TypeToClassConverter;
import io.github.springwolf.core.configuration.docket.AsyncApiDocketService;
import io.github.springwolf.core.configuration.docket.DefaultAsyncApiDocketService;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigConstants;
@@ -161,7 +163,22 @@ public class SpringwolfAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public PayloadClassExtractor payloadClassExtractor(SpringwolfConfigProperties springwolfConfigProperties) {
- return new PayloadClassExtractor(springwolfConfigProperties);
+ public TypeToClassConverter typeToClassConverter(SpringwolfConfigProperties springwolfConfigProperties) {
+ return new TypeToClassConverter(springwolfConfigProperties);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public PayloadClassExtractor payloadClassExtractor(TypeToClassConverter typeToClassConverter) {
+ return new PayloadClassExtractor(typeToClassConverter);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public PayloadService payloadService(
+ PayloadClassExtractor payloadClassExtractor,
+ ComponentsService componentsService,
+ SpringwolfConfigProperties properties) {
+ return new PayloadService(payloadClassExtractor, componentsService, properties);
}
}
diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfScannerConfiguration.java b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfScannerConfiguration.java
index a0c9e7d8..ab416da7 100644
--- a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfScannerConfiguration.java
+++ b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/SpringwolfScannerConfiguration.java
@@ -17,6 +17,7 @@ import io.github.springwolf.core.asyncapi.scanners.classes.spring.ComponentClass
import io.github.springwolf.core.asyncapi.scanners.classes.spring.ConfigurationClassScanner;
import io.github.springwolf.core.asyncapi.scanners.common.AsyncAnnotationScanner;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
import io.github.springwolf.core.asyncapi.scanners.operations.annotations.AsyncAnnotationOperationsScanner;
import io.github.springwolf.core.configuration.docket.AsyncApiDocketService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -74,6 +75,7 @@ public class SpringwolfScannerConfiguration {
ComponentsService componentsService,
AsyncApiDocketService asyncApiDocketService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
return new AsyncAnnotationChannelsScanner<>(
@@ -82,6 +84,7 @@ public class SpringwolfScannerConfiguration {
componentsService,
asyncApiDocketService,
payloadClassExtractor,
+ payloadService,
operationBindingProcessors,
messageBindingProcessors);
}
@@ -96,6 +99,7 @@ public class SpringwolfScannerConfiguration {
SpringwolfClassScanner springwolfClassScanner,
ComponentsService componentsService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
return new AsyncAnnotationOperationsScanner<>(
@@ -103,6 +107,7 @@ public class SpringwolfScannerConfiguration {
springwolfClassScanner,
componentsService,
payloadClassExtractor,
+ payloadService,
operationBindingProcessors,
messageBindingProcessors);
}
@@ -118,6 +123,7 @@ public class SpringwolfScannerConfiguration {
ComponentsService componentsService,
AsyncApiDocketService asyncApiDocketService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
return new AsyncAnnotationChannelsScanner<>(
@@ -126,6 +132,7 @@ public class SpringwolfScannerConfiguration {
componentsService,
asyncApiDocketService,
payloadClassExtractor,
+ payloadService,
operationBindingProcessors,
messageBindingProcessors);
}
@@ -140,6 +147,7 @@ public class SpringwolfScannerConfiguration {
SpringwolfClassScanner springwolfClassScanner,
ComponentsService componentsService,
PayloadClassExtractor payloadClassExtractor,
+ PayloadService payloadService,
List<OperationBindingProcessor> operationBindingProcessors,
List<MessageBindingProcessor> messageBindingProcessors) {
return new AsyncAnnotationOperationsScanner<>(
@@ -147,6 +155,7 @@ public class SpringwolfScannerConfiguration {
springwolfClassScanner,
componentsService,
payloadClassExtractor,
+ payloadService,
operationBindingProcessors,
messageBindingProcessors);
}
diff --git a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/AsyncAnnotationChannelsScannerTest.java b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/AsyncAnnotationChannelsScannerTest.java
index 39b2002d..7e4bdb5c 100644
--- a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/AsyncAnnotationChannelsScannerTest.java
+++ b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/AsyncAnnotationChannelsScannerTest.java
@@ -28,6 +28,8 @@ import io.github.springwolf.core.asyncapi.scanners.channels.AsyncAnnotationChann
import io.github.springwolf.core.asyncapi.scanners.classes.ClassScanner;
import io.github.springwolf.core.asyncapi.scanners.common.AsyncAnnotationScanner;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.TypeToClassConverter;
import io.github.springwolf.core.configuration.docket.AsyncApiDocket;
import io.github.springwolf.core.configuration.docket.AsyncApiDocketService;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
@@ -85,7 +87,10 @@ class AsyncAnnotationChannelsScannerTest {
new DefaultComponentsService(emptyList(), emptyList(), swaggerSchemaUtil, properties);
private final AsyncApiDocketService asyncApiDocketService = mock(AsyncApiDocketService.class);
- private final PayloadClassExtractor payloadClassExtractor = new PayloadClassExtractor(properties);
+ private final TypeToClassConverter typeToClassConverter = new TypeToClassConverter(properties);
+ private final PayloadClassExtractor payloadClassExtractor = new PayloadClassExtractor(typeToClassConverter);
+ private final PayloadService payloadService =
+ new PayloadService(payloadClassExtractor, componentsService, properties);
private final List<OperationBindingProcessor> operationBindingProcessors =
List.of(new TestOperationBindingProcessor());
@@ -99,6 +104,7 @@ class AsyncAnnotationChannelsScannerTest {
componentsService,
asyncApiDocketService,
payloadClassExtractor,
+ payloadService,
operationBindingProcessors,
messageBindingProcessors);
diff --git a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerIntegrationTest.java b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerIntegrationTest.java
index 11e2dec6..3671c992 100644
--- a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerIntegrationTest.java
+++ b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerIntegrationTest.java
@@ -20,6 +20,8 @@ import io.github.springwolf.core.asyncapi.components.examples.walkers.json.Examp
import io.github.springwolf.core.asyncapi.components.headers.AsyncHeadersNotDocumented;
import io.github.springwolf.core.asyncapi.scanners.bindings.BindingFactory;
import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadClassExtractor;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadService;
+import io.github.springwolf.core.asyncapi.scanners.common.payload.TypeToClassConverter;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -48,7 +50,9 @@ import static org.assertj.core.api.Assertions.assertThat;
SpringAnnotationClassLevelChannelsScannerIntegrationTest.TestBindingFactory.class,
DefaultComponentsService.class,
SwaggerSchemaUtil.class,
+ PayloadService.class,
PayloadClassExtractor.class,
+ TypeToClassConverter.class,
DefaultSchemaWalker.class,
SchemaWalkerProvider.class,
ExampleJsonValueGenerator.class,
@@ -60,7 +64,7 @@ class SpringAnnotationClassLevelChannelsScannerIntegrationTest {
BindingFactory<TestClassListener> bindingFactory;
@Autowired
- PayloadClassExtractor payloadClassExtractor;
+ PayloadService payloadService;
@Autowired
ComponentsService componentsService;
@@ -74,7 +78,7 @@ class SpringAnnotationClassLevelChannelsScannerIntegrationTest {
TestMethodListener.class,
this.bindingFactory,
new AsyncHeadersNotDocumented(),
- payloadClassExtractor,
+ payloadService,
componentsService);
}
diff --git a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerTest.java b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/channels/annotations/SpringAnnotationClassLevelChannelsScannerTest.java
index 9f0ba78b..601cf424 10…1 parent efabf30 commit baa8627
File tree
60 files changed
+935
-379
lines changed- springwolf-add-ons/springwolf-common-model-converters/src
- main/java/io/github/springwolf/addons/common_model_converters/converters/monetaryamount
- test/java/io/github/springwolf/addons/common_model_converters/converters/monetaryamount
- springwolf-asyncapi/src/main/java/io/github/springwolf/asyncapi/v3/model
- channel/message
- schema
- springwolf-core/src
- main/java/io/github/springwolf/core
- asyncapi
- components
- headers
- scanners
- channels
- annotations
- common
- payload
- operations/annotations
- configuration
- test/java/io/github/springwolf/core
- asyncapi/scanners
- channels/annotations
- common/payload
- operations/annotations
- integrationtests
- springwolf-examples/springwolf-kafka-example/src
- main/java/io/github/springwolf/examples/kafka/consumers
- test
- java/io/github/springwolf/examples/kafka
- resources
- springwolf-plugins
- springwolf-amqp-plugin/src
- main/java/io/github/springwolf/plugins/amqp
- asyncapi/components/headers
- configuration
- test/java/io/github/springwolf/plugins/amqp/configuration
- springwolf-cloud-stream-plugin/src
- main/java/io/github/springwolf/plugins/cloudstream
- asyncapi/scanners
- channels
- common
- configuration
- test/java/io/github/springwolf/plugins/cloudstream/asyncapi/scanners
- channels
- common
- springwolf-jms-plugin/src
- main/java/io/github/springwolf/plugins/jms/configuration
- test/java/io/github/springwolf/plugins/jms
- configuration
- controller
- springwolf-kafka-plugin/src
- main/java/io/github/springwolf/plugins/kafka
- asyncapi/components/header
- configuration
- test/java/io/github/springwolf/plugins/kafka
- configuration
- controller
- springwolf-sns-plugin/src/test/java/io/github/springwolf/plugins/sns/configuration
- springwolf-sqs-plugin/src
- main/java/io/github/springwolf/plugins/sqs/configuration
- test/java/io/github/springwolf/plugins/sqs/configuration
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
60 files changed
+935
-379
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
23 | 39 | | |
24 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
25 | 45 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
27 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
28 | 31 | | |
| 32 | + | |
29 | 33 | | |
30 | 34 | | |
31 | 35 | | |
| |||
36 | 40 | | |
37 | 41 | | |
38 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
39 | 50 | | |
40 | 51 | | |
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/ComponentsService.java
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| |||
Lines changed: 55 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
63 | 73 | | |
64 | 74 | | |
65 | 75 | | |
| |||
81 | 91 | | |
82 | 92 | | |
83 | 93 | | |
| 94 | + | |
84 | 95 | | |
85 | 96 | | |
86 | 97 | | |
| |||
90 | 101 | | |
91 | 102 | | |
92 | 103 | | |
93 | | - | |
| 104 | + | |
94 | 105 | | |
95 | | - | |
| 106 | + | |
96 | 107 | | |
97 | | - | |
98 | | - | |
99 | | - | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
100 | 111 | | |
101 | 112 | | |
102 | 113 | | |
| |||
130 | 141 | | |
131 | 142 | | |
132 | 143 | | |
133 | | - | |
| 144 | + | |
134 | 145 | | |
135 | 146 | | |
136 | 147 | | |
| 148 | + | |
137 | 149 | | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
138 | 178 | | |
139 | 179 | | |
140 | 180 | | |
| |||
161 | 201 | | |
162 | 202 | | |
163 | 203 | | |
164 | | - | |
| 204 | + | |
165 | 205 | | |
166 | | - | |
| 206 | + | |
167 | 207 | | |
168 | 208 | | |
169 | 209 | | |
| |||
181 | 221 | | |
182 | 222 | | |
183 | 223 | | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
184 | 231 | | |
185 | 232 | | |
186 | 233 | | |
| |||
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | | - | |
| 8 | + | |
8 | 9 | | |
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | | - | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
0 commit comments