From 2b7dafeeb8b35b810f957b609ec8b3dc3c37b28a Mon Sep 17 00:00:00 2001 From: Timon Back Date: Mon, 20 Nov 2023 20:15:48 +0100 Subject: [PATCH] Chore/align cloudstream example (#464) * chore(cloud-stream): align example * chore(cloud-stream): fix cloud-stream message description the description is part of the schema, therefore removing the duplicate in the message (aligns with other plugins) --- .../AbstractClassLevelListenerScanner.java | 1 + .../AbstractMethodLevelListenerScanner.java | 1 + ...ringwolfCloudstreamExampleApplication.java | 23 ---- .../CloudstreamConfiguration.java | 28 +++++ .../cloudstream/dtos/AnotherPayloadDto.java | 23 ++++ .../cloudstream/dtos/ExamplePayloadDto.java | 30 +++++ .../cloudstream/payload/ConsumerPayload.java | 14 --- .../cloudstream/payload/InputPayload.java | 19 ---- .../cloudstream/payload/OutputPayload.java | 23 ---- .../src/main/resources/application.properties | 6 +- .../src/test/resources/asyncapi.json | 103 +++++++++--------- .../build.gradle | 1 + .../CloudStreamFunctionChannelsScanner.java | 6 +- 13 files changed, 142 insertions(+), 136 deletions(-) create mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/configuration/CloudstreamConfiguration.java create mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/AnotherPayloadDto.java create mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/ExamplePayloadDto.java delete mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/ConsumerPayload.java delete mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/InputPayload.java delete mode 100644 springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/OutputPayload.java diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractClassLevelListenerScanner.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractClassLevelListenerScanner.java index 15ba53f28..562b346f5 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractClassLevelListenerScanner.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractClassLevelListenerScanner.java @@ -172,6 +172,7 @@ private Message buildMessage(Method method) { return Message.builder() .name(payloadType.getName()) .title(payloadType.getSimpleName()) + .description(null) .payload(PayloadReference.fromModelName(modelName)) .headers(HeaderReference.fromModelName(headerModelName)) .bindings(buildMessageBinding(method)) diff --git a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractMethodLevelListenerScanner.java b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractMethodLevelListenerScanner.java index 2fe477e4e..b491991d6 100644 --- a/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractMethodLevelListenerScanner.java +++ b/springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/annotation/AbstractMethodLevelListenerScanner.java @@ -132,6 +132,7 @@ private ChannelItem buildChannel( Message message = Message.builder() .name(payloadType.getName()) .title(payloadType.getSimpleName()) + .description(null) .payload(PayloadReference.fromModelName(modelName)) .headers(HeaderReference.fromModelName(headerModelName)) .bindings(messageBinding) diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/SpringwolfCloudstreamExampleApplication.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/SpringwolfCloudstreamExampleApplication.java index 99bacc6cc..50c98eb12 100644 --- a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/SpringwolfCloudstreamExampleApplication.java +++ b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/SpringwolfCloudstreamExampleApplication.java @@ -1,36 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 package io.github.stavshamir.springwolf.example.cloudstream; -import io.github.stavshamir.springwolf.example.cloudstream.payload.ConsumerPayload; -import io.github.stavshamir.springwolf.example.cloudstream.payload.InputPayload; -import io.github.stavshamir.springwolf.example.cloudstream.payload.OutputPayload; -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.streams.kstream.KStream; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; - -import java.util.function.Consumer; -import java.util.function.Function; @SpringBootApplication -@Slf4j public class SpringwolfCloudstreamExampleApplication { public static void main(String[] args) { SpringApplication.run(SpringwolfCloudstreamExampleApplication.class, args); } - - @Bean - public Function, KStream> process() { - return input -> input.peek((k, v) -> log.info("Received payload: {}", v)) - .mapValues( - v -> new OutputPayload(v.getFoo().stream().findFirst().orElse("list was empty"), v.getBar())) - .peek((k, v) -> log.info("Publishing output: {}", v)); - } - - @Bean - public Consumer consumerMethod() { - return input -> log.info("Consumed: {}", input); - } } diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/configuration/CloudstreamConfiguration.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/configuration/CloudstreamConfiguration.java new file mode 100644 index 000000000..80fcf85f9 --- /dev/null +++ b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/configuration/CloudstreamConfiguration.java @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +package io.github.stavshamir.springwolf.example.cloudstream.configuration; + +import io.github.stavshamir.springwolf.example.cloudstream.dtos.AnotherPayloadDto; +import io.github.stavshamir.springwolf.example.cloudstream.dtos.ExamplePayloadDto; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.streams.kstream.KStream; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.function.Consumer; +import java.util.function.Function; + +@Slf4j +@Configuration +public class CloudstreamConfiguration { + @Bean + public Function, KStream> process() { + return input -> input.peek((k, v) -> log.info("Received new message in example-topic: {}", input)) + .mapValues(v -> new AnotherPayloadDto("foo", v)) + .peek((k, v) -> log.info("Publishing output: {}", v)); + } + + @Bean + public Consumer consumerMethod() { + return input -> log.info("Received new message in another-topic: {}", input.toString()); + } +} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/AnotherPayloadDto.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/AnotherPayloadDto.java new file mode 100644 index 000000000..624e2156e --- /dev/null +++ b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/AnotherPayloadDto.java @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +package io.github.stavshamir.springwolf.example.cloudstream.dtos; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +@Schema(description = "Another payload model") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AnotherPayloadDto { + + @Schema(description = "Foo field", example = "bar", requiredMode = NOT_REQUIRED) + private String foo; + + @Schema(description = "Example field", requiredMode = REQUIRED) + private ExamplePayloadDto example; +} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/ExamplePayloadDto.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/ExamplePayloadDto.java new file mode 100644 index 000000000..82e7e65db --- /dev/null +++ b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/dtos/ExamplePayloadDto.java @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +package io.github.stavshamir.springwolf.example.cloudstream.dtos; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +@Schema(description = "Example payload model") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ExamplePayloadDto { + @Schema(description = "Some string field", example = "some string value", requiredMode = REQUIRED) + private String someString; + + @Schema(description = "Some long field", example = "5") + private long someLong; + + @Schema(description = "Some enum field", example = "FOO2", requiredMode = REQUIRED) + private ExampleEnum someEnum; + + public enum ExampleEnum { + FOO1, + FOO2, + FOO3 + } +} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/ConsumerPayload.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/ConsumerPayload.java deleted file mode 100644 index 674d9696d..000000000 --- a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/ConsumerPayload.java +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -package io.github.stavshamir.springwolf.example.cloudstream.payload; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ConsumerPayload { - - private String payloadString; -} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/InputPayload.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/InputPayload.java deleted file mode 100644 index de8e7eff6..000000000 --- a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/InputPayload.java +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -package io.github.stavshamir.springwolf.example.cloudstream.payload; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -@Schema(description = "Input payload model") -@Data -@AllArgsConstructor -@NoArgsConstructor -public class InputPayload { - - private List foo; - private int bar; -} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/OutputPayload.java b/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/OutputPayload.java deleted file mode 100644 index e0cb10a3b..000000000 --- a/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/payload/OutputPayload.java +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -package io.github.stavshamir.springwolf.example.cloudstream.payload; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Schema(description = "Output payload model") -@Data -@AllArgsConstructor -@NoArgsConstructor -public class OutputPayload { - - @Schema( - description = "Some string field", - example = "some string value", - requiredMode = Schema.RequiredMode.REQUIRED) - private String someString; - - @Schema(description = "Some long field", example = "5") - private long someLong; -} diff --git a/springwolf-examples/springwolf-cloud-stream-example/src/main/resources/application.properties b/springwolf-examples/springwolf-cloud-stream-example/src/main/resources/application.properties index 420b1bd2b..f9fe72611 100644 --- a/springwolf-examples/springwolf-cloud-stream-example/src/main/resources/application.properties +++ b/springwolf-examples/springwolf-cloud-stream-example/src/main/resources/application.properties @@ -7,9 +7,9 @@ spring.application.name=Springwolf example project - Cloud Stream # Spring cloud configuration spring.cloud.stream.kafka.streams.binder.applicationId=springwolf-cloud-stream-example spring.kafka.bootstrap-servers=${BOOTSTRAP_SERVER:localhost:29092} -spring.cloud.stream.bindings.process-in-0.destination=input-topic -spring.cloud.stream.bindings.process-out-0.destination=output-topic -spring.cloud.stream.bindings.consumerMethod-in-0.destination=consumer-method-input-topic +spring.cloud.stream.bindings.process-in-0.destination=example-topic +spring.cloud.stream.bindings.process-out-0.destination=another-topic +spring.cloud.stream.bindings.consumerMethod-in-0.destination=another-topic ######### 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 0fe9e45b6..4b93d45d0 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 @@ -21,19 +21,19 @@ } }, "channels": { - "consumer-method-input-topic": { - "publish": { - "operationId": "consumer-method-input-topic_publish_consumerMethod", + "another-topic": { + "subscribe": { + "operationId": "another-topic_subscribe_process", "description": "Auto-generated description", "bindings": { "kafka": { } }, "message": { "schemaFormat": "application/vnd.oai.openapi+json;version=3.0.0", - "name": "io.github.stavshamir.springwolf.example.cloudstream.payload.ConsumerPayload", - "title": "ConsumerPayload", + "name": "io.github.stavshamir.springwolf.example.cloudstream.dtos.AnotherPayloadDto", + "title": "AnotherPayloadDto", "payload": { - "$ref": "#/components/schemas/ConsumerPayload" + "$ref": "#/components/schemas/AnotherPayloadDto" }, "headers": { "$ref": "#/components/schemas/HeadersNotDocumented" @@ -43,23 +43,18 @@ } } }, - "bindings": { - "kafka": { } - } - }, - "input-topic": { "publish": { - "operationId": "input-topic_publish_process", + "operationId": "another-topic_publish_consumerMethod", "description": "Auto-generated description", "bindings": { "kafka": { } }, "message": { "schemaFormat": "application/vnd.oai.openapi+json;version=3.0.0", - "name": "io.github.stavshamir.springwolf.example.cloudstream.payload.InputPayload", - "title": "InputPayload", + "name": "io.github.stavshamir.springwolf.example.cloudstream.dtos.AnotherPayloadDto", + "title": "AnotherPayloadDto", "payload": { - "$ref": "#/components/schemas/InputPayload" + "$ref": "#/components/schemas/AnotherPayloadDto" }, "headers": { "$ref": "#/components/schemas/HeadersNotDocumented" @@ -73,19 +68,19 @@ "kafka": { } } }, - "output-topic": { - "subscribe": { - "operationId": "output-topic_subscribe_process", + "example-topic": { + "publish": { + "operationId": "example-topic_publish_process", "description": "Auto-generated description", "bindings": { "kafka": { } }, "message": { "schemaFormat": "application/vnd.oai.openapi+json;version=3.0.0", - "name": "io.github.stavshamir.springwolf.example.cloudstream.payload.OutputPayload", - "title": "OutputPayload", + "name": "io.github.stavshamir.springwolf.example.cloudstream.dtos.ExamplePayloadDto", + "title": "ExamplePayloadDto", "payload": { - "$ref": "#/components/schemas/OutputPayload" + "$ref": "#/components/schemas/ExamplePayloadDto" }, "headers": { "$ref": "#/components/schemas/HeadersNotDocumented" @@ -102,50 +97,48 @@ }, "components": { "schemas": { - "ConsumerPayload": { - "type": "object", - "properties": { - "payloadString": { - "type": "string" - } - }, - "example": { - "payloadString": "string" - } - }, - "HeadersNotDocumented": { - "type": "object", - "properties": { }, - "example": { } - }, - "InputPayload": { + "AnotherPayloadDto": { + "required": [ + "example" + ], "type": "object", "properties": { - "bar": { - "type": "integer", - "format": "int32" + "example": { + "$ref": "#/components/schemas/ExamplePayloadDto" }, "foo": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "description": "Foo field", + "example": "bar" } }, - "description": "Input payload model", + "description": "Another payload model", "example": { - "bar": 0, - "foo": [ - "string" - ] + "example": { + "someEnum": "FOO2", + "someLong": 5, + "someString": "some string value" + }, + "foo": "bar" } }, - "OutputPayload": { + "ExamplePayloadDto": { "required": [ + "someEnum", "someString" ], "type": "object", "properties": { + "someEnum": { + "type": "string", + "description": "Some enum field", + "example": "FOO2", + "enum": [ + "FOO1", + "FOO2", + "FOO3" + ] + }, "someLong": { "type": "integer", "description": "Some long field", @@ -158,11 +151,17 @@ "example": "some string value" } }, - "description": "Output payload model", + "description": "Example payload model", "example": { + "someEnum": "FOO2", "someLong": 5, "someString": "some string value" } + }, + "HeadersNotDocumented": { + "type": "object", + "properties": { }, + "example": { } } } }, diff --git a/springwolf-plugins/springwolf-cloud-stream-plugin/build.gradle b/springwolf-plugins/springwolf-cloud-stream-plugin/build.gradle index e7a08d325..c221165be 100644 --- a/springwolf-plugins/springwolf-cloud-stream-plugin/build.gradle +++ b/springwolf-plugins/springwolf-cloud-stream-plugin/build.gradle @@ -20,6 +20,7 @@ dependencies { api project(":springwolf-core") implementation "com.asyncapi:asyncapi-core:${asyncapiCoreVersion}" + implementation "org.slf4j:slf4j-api:${slf4jApiVersion}" implementation "org.springframework:spring-context" diff --git a/springwolf-plugins/springwolf-cloud-stream-plugin/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/cloudstream/CloudStreamFunctionChannelsScanner.java b/springwolf-plugins/springwolf-cloud-stream-plugin/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/cloudstream/CloudStreamFunctionChannelsScanner.java index 4f471ed58..81ebc2a63 100644 --- a/springwolf-plugins/springwolf-cloud-stream-plugin/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/cloudstream/CloudStreamFunctionChannelsScanner.java +++ b/springwolf-plugins/springwolf-cloud-stream-plugin/src/main/java/io/github/stavshamir/springwolf/asyncapi/scanners/channels/cloudstream/CloudStreamFunctionChannelsScanner.java @@ -64,12 +64,14 @@ private Map.Entry toChannelEntry(FunctionalChannelBeanData } private ChannelItem buildChannel(FunctionalChannelBeanData beanData, String operationId) { - String modelName = schemasService.register(beanData.getPayloadType()); + Class payloadType = beanData.getPayloadType(); + String modelName = schemasService.register(payloadType); String headerModelName = schemasService.register(AsyncHeaders.NOT_DOCUMENTED); Message message = Message.builder() - .name(beanData.getPayloadType().getName()) + .name(payloadType.getName()) .title(modelName) + .description(null) .payload(PayloadReference.fromModelName(modelName)) .headers(HeaderReference.fromModelName(headerModelName)) .bindings(buildMessageBinding())