Skip to content

Commit adc1d80

Browse files
sam0r040timonback
andauthored
feat(core): add configuration option to use fully qualified names in schemas (#393)
* feat(core): add configuration option to use fully qualified names in schemas default is false (unchanged behavior) Co-authored-by: Timon Back <[email protected]> * feat(core): rebase to master * test(core): update DefaultSchemaServiceTest * feat(example): Use fqn in example * feat(ui): show only schema type (not fqn) in ui * feat(core): Use class name for title, not fqn * feat(ui): ui can show fqn payload * test(plugin): add SpringwolfConfigProperties in test context * feat(core): use swagger-core getUseFqn to reset fqn * test(amqp): update asyncapi_withdocketfromenvironment.json after rebase --------- Co-authored-by: Timon Back <[email protected]> Co-authored-by: Timon Back <[email protected]>
1 parent 89c7b00 commit adc1d80

File tree

36 files changed

+347
-229
lines changed

36 files changed

+347
-229
lines changed

springwolf-core/src/main/java/io/github/stavshamir/springwolf/SpringwolfAutoConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ public ChannelsService channelsService(List<? extends ChannelsScanner> channelsS
6767

6868
@Bean
6969
@ConditionalOnMissingBean
70-
public SchemasService schemasService(List<ModelConverter> modelConverters, ExampleGenerator exampleGenerator) {
71-
return new DefaultSchemasService(modelConverters, exampleGenerator);
70+
public SchemasService schemasService(
71+
List<ModelConverter> modelConverters,
72+
ExampleGenerator exampleGenerator,
73+
SpringwolfConfigProperties springwolfConfigProperties) {
74+
return new DefaultSchemasService(modelConverters, exampleGenerator, springwolfConfigProperties);
7275
}
7376

7477
@Bean

springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractClassLevelListenerScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private Message buildMessage(Method method) {
178178

179179
return Message.builder()
180180
.name(payloadType.getName())
181-
.title(modelName)
181+
.title(payloadType.getSimpleName())
182182
.payload(PayloadReference.fromModelName(modelName))
183183
.headers(HeaderReference.fromModelName(headerModelName))
184184
.bindings(buildMessageBinding(method))

springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractMethodLevelListenerScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ private ChannelItem buildChannel(
123123

124124
Message message = Message.builder()
125125
.name(payloadType.getName())
126-
.title(modelName)
126+
.title(payloadType.getSimpleName())
127127
.payload(PayloadReference.fromModelName(modelName))
128128
.headers(HeaderReference.fromModelName(headerModelName))
129129
.bindings(messageBinding)

springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/operationdata/AbstractOperationDataScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private Message buildMessage(OperationData operationData) {
109109

110110
var builder = Message.builder()
111111
.name(payloadType.getName())
112-
.title(modelName)
112+
.title(payloadType.getSimpleName())
113113
.description(description)
114114
.payload(PayloadReference.fromModelName(modelName))
115115
.headers(HeaderReference.fromModelName(headerModelName))

springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/properties/SpringwolfConfigProperties.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ public enum InitMode {
4242
*/
4343
private InitMode initMode = InitMode.FAIL_FAST;
4444

45+
/**
46+
* Use fully qualified names for the schema classes
47+
*
48+
* Example:
49+
* useFqn = true -> java.lang.String
50+
* useFqn = false -> String
51+
*/
52+
private boolean useFqn = false;
53+
4554
@Nullable
4655
private Endpoint endpoint;
4756

springwolf-core/src/main/java/io/github/stavshamir/springwolf/schemas/DefaultSchemasService.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
package io.github.stavshamir.springwolf.schemas;
33

44
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.AsyncHeaders;
5+
import io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigProperties;
56
import io.github.stavshamir.springwolf.schemas.example.ExampleGenerator;
67
import io.swagger.v3.core.converter.ModelConverter;
78
import io.swagger.v3.core.converter.ModelConverters;
9+
import io.swagger.v3.core.jackson.TypeNameResolver;
810
import io.swagger.v3.oas.models.media.MapSchema;
911
import io.swagger.v3.oas.models.media.Schema;
1012
import io.swagger.v3.oas.models.media.StringSchema;
@@ -15,20 +17,26 @@
1517
import java.util.List;
1618
import java.util.Map;
1719
import java.util.Set;
20+
import java.util.function.Function;
1821

1922
@Slf4j
2023
public class DefaultSchemasService implements SchemasService {
2124

2225
private final ModelConverters converter = ModelConverters.getInstance();
2326
private final ExampleGenerator exampleGenerator;
27+
private final SpringwolfConfigProperties properties;
2428

2529
private final Map<String, Schema> definitions = new HashMap<>();
2630
private Map<String, Schema> finalizedDefinitions = null;
2731

28-
public DefaultSchemasService(List<ModelConverter> externalModelConverters, ExampleGenerator exampleGenerator) {
32+
public DefaultSchemasService(
33+
List<ModelConverter> externalModelConverters,
34+
ExampleGenerator exampleGenerator,
35+
SpringwolfConfigProperties properties) {
2936

3037
externalModelConverters.forEach(converter::addConverter);
3138
this.exampleGenerator = exampleGenerator;
39+
this.properties = properties;
3240
}
3341

3442
@Override
@@ -61,10 +69,10 @@ public String register(AsyncHeaders headers) {
6169
public String register(Class<?> type) {
6270
log.debug("Registering schema for {}", type.getSimpleName());
6371

64-
Map<String, Schema> schemas = converter.readAll(type);
72+
Map<String, Schema> schemas = runWithFqnSetting((unused) -> converter.readAll(type));
6573
this.definitions.putAll(schemas);
6674

67-
if (schemas.size() == 0 && type.equals(String.class)) {
75+
if (schemas.isEmpty() && type.equals(String.class)) {
6876
this.definitions.put("String", new StringSchema());
6977
return "String";
7078
}
@@ -81,6 +89,20 @@ public String register(Class<?> type) {
8189
return type.getSimpleName();
8290
}
8391

92+
private <R> R runWithFqnSetting(Function<Void, R> callable) {
93+
boolean previousUseFqn = TypeNameResolver.std.getUseFqn();
94+
if (properties.isUseFqn()) {
95+
TypeNameResolver.std.setUseFqn(true);
96+
}
97+
98+
R result = callable.apply(null);
99+
100+
if (properties.isUseFqn()) {
101+
TypeNameResolver.std.setUseFqn(previousUseFqn);
102+
}
103+
return result;
104+
}
105+
84106
private void removeSwaggerSchemaFields(String schemaName, Schema schema) {
85107
schema.setAdditionalProperties(null);
86108

springwolf-core/src/test/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/TestMethodLevelListenerScannerIntegrationTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.AsyncHeaders;
1010
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.HeaderReference;
1111
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;
12+
import io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigProperties;
1213
import io.github.stavshamir.springwolf.schemas.DefaultSchemasService;
1314
import io.github.stavshamir.springwolf.schemas.example.ExampleJsonGenerator;
1415
import lombok.Data;
@@ -33,7 +34,12 @@
3334

3435
@ExtendWith(SpringExtension.class)
3536
@ContextConfiguration(
36-
classes = {TestMethodLevelListenerScanner.class, DefaultSchemasService.class, ExampleJsonGenerator.class})
37+
classes = {
38+
TestMethodLevelListenerScanner.class,
39+
DefaultSchemasService.class,
40+
ExampleJsonGenerator.class,
41+
SpringwolfConfigProperties.class
42+
})
3743
class TestMethodLevelListenerScannerIntegrationTest {
3844

3945
@Autowired

springwolf-core/src/test/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/operationdata/ConsumerOperationDataScannerIntegrationTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.HeaderReference;
1515
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;
1616
import io.github.stavshamir.springwolf.configuration.AsyncApiDocketService;
17+
import io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigProperties;
1718
import io.github.stavshamir.springwolf.schemas.DefaultSchemasService;
1819
import io.github.stavshamir.springwolf.schemas.example.ExampleJsonGenerator;
1920
import io.swagger.v3.oas.annotations.media.Schema;
@@ -35,7 +36,12 @@
3536

3637
@ExtendWith(SpringExtension.class)
3738
@ContextConfiguration(
38-
classes = {ConsumerOperationDataScanner.class, DefaultSchemasService.class, ExampleJsonGenerator.class})
39+
classes = {
40+
ConsumerOperationDataScanner.class,
41+
DefaultSchemasService.class,
42+
ExampleJsonGenerator.class,
43+
SpringwolfConfigProperties.class,
44+
})
3945
class ConsumerOperationDataScannerIntegrationTest {
4046

4147
@Autowired
@@ -73,8 +79,8 @@ void allFieldsConsumerData() {
7379
.bindings(Map.of("kafka", new KafkaOperationBinding()))
7480
.message(Message.builder()
7581
.name(ExamplePayloadDto.class.getName())
76-
.description(messageDescription)
7782
.title(ExamplePayloadDto.class.getSimpleName())
83+
.description(messageDescription)
7884
.payload(PayloadReference.fromModelName(ExamplePayloadDto.class.getSimpleName()))
7985
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_DOCUMENTED.getSchemaName()))
8086
.bindings(Map.of("kafka", new KafkaMessageBinding()))
@@ -144,16 +150,16 @@ void multipleConsumersForSameTopic() {
144150
Set<Message> messages = Set.of(
145151
Message.builder()
146152
.name(ExamplePayloadDto.class.getName())
147-
.description(messageDescription1)
148153
.title(ExamplePayloadDto.class.getSimpleName())
154+
.description(messageDescription1)
149155
.payload(PayloadReference.fromModelName(ExamplePayloadDto.class.getSimpleName()))
150156
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_DOCUMENTED.getSchemaName()))
151157
.bindings(Map.of("kafka", new KafkaMessageBinding()))
152158
.build(),
153159
Message.builder()
154160
.name(AnotherExamplePayloadDto.class.getName())
155-
.description(messageDescription2)
156161
.title(AnotherExamplePayloadDto.class.getSimpleName())
162+
.description(messageDescription2)
157163
.payload(PayloadReference.fromModelName(AnotherExamplePayloadDto.class.getSimpleName()))
158164
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_USED.getSchemaName()))
159165
.bindings(Map.of("kafka", new KafkaMessageBinding()))

springwolf-core/src/test/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/operationdata/ProducerOperationDataScannerIntegrationTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.HeaderReference;
1515
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;
1616
import io.github.stavshamir.springwolf.configuration.AsyncApiDocketService;
17+
import io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigProperties;
1718
import io.github.stavshamir.springwolf.schemas.DefaultSchemasService;
1819
import io.github.stavshamir.springwolf.schemas.example.ExampleJsonGenerator;
1920
import io.swagger.v3.oas.annotations.media.Schema;
@@ -35,7 +36,12 @@
3536

3637
@ExtendWith(SpringExtension.class)
3738
@ContextConfiguration(
38-
classes = {ProducerOperationDataScanner.class, DefaultSchemasService.class, ExampleJsonGenerator.class})
39+
classes = {
40+
ProducerOperationDataScanner.class,
41+
DefaultSchemasService.class,
42+
ExampleJsonGenerator.class,
43+
SpringwolfConfigProperties.class,
44+
})
3945
class ProducerOperationDataScannerIntegrationTest {
4046

4147
@Autowired
@@ -73,8 +79,8 @@ void allFieldsProducerData() {
7379
.bindings(Map.of("kafka", new KafkaOperationBinding()))
7480
.message(Message.builder()
7581
.name(ExamplePayloadDto.class.getName())
76-
.description(messageDescription1)
7782
.title(ExamplePayloadDto.class.getSimpleName())
83+
.description(messageDescription1)
7884
.payload(PayloadReference.fromModelName(ExamplePayloadDto.class.getSimpleName()))
7985
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_DOCUMENTED.getSchemaName()))
8086
.bindings(Map.of("kafka", new KafkaMessageBinding()))
@@ -144,16 +150,16 @@ void multipleProducersForSameTopic() {
144150
Set<Message> messages = Set.of(
145151
Message.builder()
146152
.name(ExamplePayloadDto.class.getName())
147-
.description(messageDescription1)
148153
.title(ExamplePayloadDto.class.getSimpleName())
154+
.description(messageDescription1)
149155
.payload(PayloadReference.fromModelName(ExamplePayloadDto.class.getSimpleName()))
150156
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_DOCUMENTED.getSchemaName()))
151157
.bindings(Map.of("kafka", new KafkaMessageBinding()))
152158
.build(),
153159
Message.builder()
154160
.name(AnotherExamplePayloadDto.class.getName())
155-
.description(messageDescription2)
156161
.title(AnotherExamplePayloadDto.class.getSimpleName())
162+
.description(messageDescription2)
157163
.payload(PayloadReference.fromModelName(AnotherExamplePayloadDto.class.getSimpleName()))
158164
.headers(HeaderReference.fromModelName(AsyncHeaders.NOT_USED.getSchemaName()))
159165
.bindings(Map.of("kafka", new KafkaMessageBinding()))

springwolf-core/src/test/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/operationdata/annotation/AsyncListenerAnnotationScannerIntegrationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.PayloadReference;
1010
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.AsyncHeaders;
1111
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.HeaderReference;
12+
import io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigProperties;
1213
import io.github.stavshamir.springwolf.schemas.DefaultSchemasService;
1314
import io.github.stavshamir.springwolf.schemas.example.ExampleJsonGenerator;
1415
import io.swagger.v3.oas.annotations.media.Schema;
@@ -36,6 +37,7 @@
3637
AsyncListenerAnnotationScanner.class,
3738
DefaultSchemasService.class,
3839
ExampleJsonGenerator.class,
40+
SpringwolfConfigProperties.class,
3941
TestOperationBindingProcessor.class
4042
})
4143
@TestPropertySource(properties = {"test.property.test-channel=test-channel", "test.property.description=description"})

0 commit comments

Comments
 (0)