From 8cd01638bb4b7111e33ab5dcf5c9b9040aef7453 Mon Sep 17 00:00:00 2001 From: Carlos Tasada Date: Fri, 2 Jun 2023 18:56:44 +0200 Subject: [PATCH] Feat: Improved docket configuration (#191) * Feat: Added default-content-type Docket configuration The configuration for `defaultContentType` was not possible via SpringBoot Properties. Now we can indicate something like `springwolf.docket.default-content-type=application/json` (or `springwolf.docket.defaultContentType=application/json` to configure the value * Feat: Added id Docket configuration It was not possible to configure the AsyncAPI identifier Now we can indicate something like `springwolf.docket.id=urn:something:something` (or `springwolf.docket.id=https://something` to configure the identifier value * chore: Add default value for defaultContentType=application/json --------- Co-authored-by: Timon Back --- .../springwolf/SpringWolfConfigProperties.java | 16 ++++++++++++++++ .../asyncapi/DefaultAsyncApiService.java | 2 ++ .../springwolf/asyncapi/types/AsyncAPI.java | 17 ++++++++++++++++- .../configuration/AsyncApiDocket.java | 15 +++++++++++++++ .../DefaultAsyncApiDocketService.java | 10 ++++++++-- .../springwolf/SpringContextTest.java | 5 +++++ .../DefaultAsyncApiDocketServiceTest.java | 3 +++ .../src/test/resources/asyncapi.json | 1 + .../src/test/resources/asyncapi.json | 1 + .../src/test/resources/asyncapi.json | 1 + 10 files changed, 68 insertions(+), 3 deletions(-) diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/SpringWolfConfigProperties.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/SpringWolfConfigProperties.java index 646815bc8..78d3b5af5 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/SpringWolfConfigProperties.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/SpringWolfConfigProperties.java @@ -41,6 +41,22 @@ public static class ConfigDocket { @Nullable private String basePackage; + /** + * Identifier of the application the AsyncAPI document is defining. + * + * @see com.asyncapi.v2._0_0.model.AsyncAPI#id + */ + @Nullable + private String id; + + /** + * A string representing the default content type to use when encoding/decoding a message's payload. + * + * @see com.asyncapi.v2._0_0.model.AsyncAPI#defaultContentType + */ + @Nullable + private String defaultContentType; + @Nullable private Map servers; diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.java index 8f244ca94..9a67ac932 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.java @@ -33,6 +33,8 @@ void buildAsyncApi() { asyncAPI = AsyncAPI.builder() .info(docket.getInfo()) + .id(docket.getId()) + .defaultContentType(docket.getDefaultContentType()) .servers(docket.getServers()) .channels(channelsService.getChannels()) .components(components) diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/types/AsyncAPI.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/types/AsyncAPI.java index 232df2129..232cf9c36 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/types/AsyncAPI.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/types/AsyncAPI.java @@ -4,7 +4,11 @@ import com.asyncapi.v2._0_0.model.channel.ChannelItem; import com.asyncapi.v2._0_0.model.info.Info; import com.asyncapi.v2._0_0.model.server.Server; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; import javax.validation.constraints.NotNull; import java.util.Collections; @@ -35,6 +39,17 @@ public class AsyncAPI { @Builder.Default private String asyncapi = "2.0.0"; + /** + * Identifier of the application the AsyncAPI document is defining. + *

+ * This field represents a unique universal identifier of the application the AsyncAPI document is defining. + * It must conform to the URI format, according to RFC3986. + *

+ * It is RECOMMENDED to use a URN to globally and uniquely identify the application during long periods of time, + * even after it becomes unavailable or ceases to exist. + */ + private String id; + /** * Required. * Provides metadata about the API. The metadata can be used by the clients if needed. diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/AsyncApiDocket.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/AsyncApiDocket.java index e19fc2d95..0ae51e1b0 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/AsyncApiDocket.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/AsyncApiDocket.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.NonNull; import lombok.Singular; +import org.springframework.http.MediaType; import java.util.List; import java.util.Map; @@ -51,4 +52,18 @@ public class AsyncApiDocket { @Singular private final List consumers; + /** + * A string representing the default content type to use when encoding/decoding a message's payload. + * + * @see Default Content Type + */ + @Builder.Default + private final String defaultContentType = MediaType.APPLICATION_JSON_VALUE; + + /** + * A string representing the default content type to use when encoding/decoding a message's payload. + * + * @see Identifier + */ + private final String id; } diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketService.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketService.java index 889584eed..e3ffe140d 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketService.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketService.java @@ -48,11 +48,17 @@ private AsyncApiDocket parseApplicationConfigProperties(SpringWolfConfigProperti Info info = buildInfo(configProperties.getDocket().getInfo()); - return AsyncApiDocket.builder() + AsyncApiDocket.AsyncApiDocketBuilder builder = AsyncApiDocket.builder() .basePackage(configProperties.getDocket().getBasePackage()) .info(info) .servers(configProperties.getDocket().getServers()) - .build(); + .id(configProperties.getDocket().getId()); + + if(configProperties.getDocket().getDefaultContentType() != null) { + builder.defaultContentType(configProperties.getDocket().getDefaultContentType()); + } + + return builder.build(); } private static Info buildInfo(@Nullable SpringWolfConfigProperties.ConfigDocket.Info info) { diff --git a/springwolf-core/src/test/java/io/github/stavshamir/springwolf/SpringContextTest.java b/springwolf-core/src/test/java/io/github/stavshamir/springwolf/SpringContextTest.java index bd911c746..f892ff55a 100644 --- a/springwolf-core/src/test/java/io/github/stavshamir/springwolf/SpringContextTest.java +++ b/springwolf-core/src/test/java/io/github/stavshamir/springwolf/SpringContextTest.java @@ -65,6 +65,8 @@ void testContextWithAsyncApiDocketBean() { "springwolf.enabled=true", "springwolf.docket.info.title=Info title was loaded from spring properties", "springwolf.docket.info.version=1.0.0", + "springwolf.docket.id=urn:io:github:stavshamir:springwolf:example", + "springwolf.docket.default-content-type=application/yaml", "springwolf.docket.base-package=io.github.stavshamir.springwolf.example", "springwolf.docket.servers.test-protocol.protocol=test", "springwolf.docket.servers.test-protocol.url=some-server:1234", @@ -81,6 +83,9 @@ void testContextWithApplicationProperties() { assertNotNull(context); assertThat(asyncApiService.getAsyncAPI()).isNotNull(); + assertThat(asyncApiService.getAsyncAPI().getInfo().getTitle()).isEqualTo("Info title was loaded from spring properties"); + assertThat(asyncApiService.getAsyncAPI().getDefaultContentType()).isEqualTo("application/yaml"); + assertThat(asyncApiService.getAsyncAPI().getId()).isEqualTo("urn:io:github:stavshamir:springwolf:example"); } } } \ No newline at end of file diff --git a/springwolf-core/src/test/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketServiceTest.java b/springwolf-core/src/test/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketServiceTest.java index 43e45d5cb..fe0ab5d54 100644 --- a/springwolf-core/src/test/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketServiceTest.java +++ b/springwolf-core/src/test/java/io/github/stavshamir/springwolf/configuration/DefaultAsyncApiDocketServiceTest.java @@ -23,6 +23,8 @@ void testConfigurationShouldMapAllPropertiesToTheDocket() { ConfigDocket configDocket = new ConfigDocket(); configDocket.setBasePackage("test-base-package"); + configDocket.setDefaultContentType("application/json"); + Server server = Server.builder() .protocol("some-protocol") .url("some-url") @@ -46,6 +48,7 @@ void testConfigurationShouldMapAllPropertiesToTheDocket() { AsyncApiDocket asyncApiDocket = docketConfiguration.getAsyncApiDocket(); // then + assertThat(asyncApiDocket.getDefaultContentType()).isEqualTo(configDocket.getDefaultContentType()); assertThat(asyncApiDocket.getServers()).isEqualTo(configDocket.getServers()); assertThat(asyncApiDocket.getInfo().getTitle()).isEqualTo(info.getTitle()); assertThat(asyncApiDocket.getInfo().getVersion()).isEqualTo(info.getVersion()); diff --git a/springwolf-examples/springwolf-amqp-example/src/test/resources/asyncapi.json b/springwolf-examples/springwolf-amqp-example/src/test/resources/asyncapi.json index 49fcf05f3..acaa9ed87 100644 --- a/springwolf-examples/springwolf-amqp-example/src/test/resources/asyncapi.json +++ b/springwolf-examples/springwolf-amqp-example/src/test/resources/asyncapi.json @@ -13,6 +13,7 @@ "name" : "Apache License 2.0" } }, + "defaultContentType" : "application/json", "servers" : { "amqp" : { "url" : "amqp:5672", diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/test/resources/asyncapi.json b/springwolf-examples/springwolf-cloud-stream-example/src/test/resources/asyncapi.json index 940216e9f..e0dd26791 100644 --- a/springwolf-examples/springwolf-cloud-stream-example/src/test/resources/asyncapi.json +++ b/springwolf-examples/springwolf-cloud-stream-example/src/test/resources/asyncapi.json @@ -13,6 +13,7 @@ "name": "Apache License 2.0" } }, + "defaultContentType" : "application/json", "servers": { "kafka": { "url": "kafka:29092", diff --git a/springwolf-examples/springwolf-kafka-example/src/test/resources/asyncapi.json b/springwolf-examples/springwolf-kafka-example/src/test/resources/asyncapi.json index 07a528194..afe2f1978 100644 --- a/springwolf-examples/springwolf-kafka-example/src/test/resources/asyncapi.json +++ b/springwolf-examples/springwolf-kafka-example/src/test/resources/asyncapi.json @@ -13,6 +13,7 @@ "name" : "Apache License 2.0" } }, + "defaultContentType" : "application/json", "servers" : { "kafka" : { "url" : "localhost:9092",