Skip to content

Commit b5fbbed

Browse files
authored
Update documentation for actuator (#92)
* Update documentation for actuator * docs: update to 1.4.0 * docs: document stomp binding and plugin * chore: add lint command * docs: update swagger version * docs: add headers page * docs: improve consumer docs * docs: add springwolf.studio-compatibility configuration * docs: add presentation link
1 parent f9b2613 commit b5fbbed

25 files changed

+232
-114
lines changed

.github/styles/config/vocabularies/Springwolf/accept.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ Kotlinx
1212
Protobuf
1313
Springfox
1414
Springwolf
15+
STOMP
1516
UI

docs/behind-the-scenes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ From there, Springwolf forwards the message to the protocol specific producer.
2020
## Plugins
2121

2222
`springwolf-core` provides the base functionality to orchestrate the scanning and building of the AsyncAPI document.
23-
The different protocol (AMQP, Cloud-Stream, JMS, Kafka, SNS, SQS) are supported through plugins.
23+
The different protocol (AMQP, Cloud-Stream, JMS, Kafka, SNS, SQS, STOMP/WebSocket) are supported through plugins.
2424
These plugins are found through the Spring dependency injection functionality.
2525
When building own scanner plugins, your plugin will need to implement the `ChannelsScanner` interface.
2626

docs/configuration/configuration.mdx

Lines changed: 32 additions & 27 deletions
Large diffs are not rendered by default.

docs/configuration/customizing.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public class AsyncApiTitleCustomizer implements AsyncApiCustomizer {
3838
}
3939
```
4040

41+
## ObjectMapper in `DefaultAsyncApiSerializerService`
42+
43+
The `DefaultAsyncApiSerializerService` is responsible for serializing the AsyncAPI document into a `String` for the Controller.
44+
45+
Use `DefaultAsyncApiSerializerService#getJsonObjectMapper()` and `DefaultAsyncApiSerializerService#getYamlObjectMapper()` to customize the `ObjectMapper`.
46+
4147
## `ChannelScanners` - Channel detection
4248

4349
All `ChannelScanner` beans are called to scan for channels.

docs/configuration/documenting-bindings.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ Associate this operation with SQS, see [operation-binding] for details.
5353
@SqsAsyncOperationBinding
5454
```
5555

56+
### `@StompAsyncOperationBinding`
57+
58+
Associate this operation with STOMP (WebSocket), see [operation-binding] for details.
59+
60+
```java
61+
@StompAsyncOperationBinding
62+
```
63+
5664
## Generic annotation
5765

5866
This binding is generic, so that any properties can be specified.
@@ -123,7 +131,7 @@ The group id that will be used during message consumption
123131

124132
The client id to identify the consumer
125133

126-
### Google PubSub binding annotations
134+
### Google PubSub
127135

128136
#### Channel Binding Object
129137

@@ -148,7 +156,7 @@ The Channel Bindings Object is used to describe the Google Cloud Pub/Sub Topic d
148156

149157
- A list of IDs of GCP regions where messages that are published to the topic may be persisted in storage
150158

151-
`Schema Settings`:The Schema Settings Object is used to describe the Google Cloud Pub/Sub SchemaSettings.
159+
`Schema Settings`: The Schema Settings Object is used to describe the Google Cloud Pub/Sub SchemaSettings.
152160

153161
- encoding: The encoding of the message
154162
- firstRevisionId: The minimum (inclusive) revision allowed for validating messages

docs/configuration/documenting-consumers.md

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ For these use-cases, Springwolf provides additional ways to explicitly add them
1111

1212
To document consumers, either:
1313

14-
- add the `@AsyncListener` annotation or
15-
- rely on the auto-detection of `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener`
14+
- rely on the auto-detection of `@JmsListener`, `@KafkaListener`, `@MessageMapping`, `@RabbitListener`, `@SendTo`, `@SendToUser`, `@SqsListener`
15+
- and/or use the `@AsyncListener` annotation
1616

1717
You are free to use both options together. Channel and operation, documented via `@AsyncListener` have a higher precedence than auto-detected annotations.
1818

19+
## Auto-detection
20+
21+
The `@JmsListener`, `@KafkaListener`, `@MessageMapping`, `@RabbitListener`, `@SendTo`, `@SendToUser`, `@SqsListener` annotations are detected automatically.
22+
There is nothing more to do.
23+
24+
Use the other option if the provided documentation is insufficient.
25+
1926
## `@AsyncListener`
2027

2128
The `@AsyncListener` annotation is added to the method of the listeners and extracts the payload from its arguments.
@@ -30,23 +37,7 @@ Below is an example to demonstrate the annotation:
3037
@AsyncListener(operation = @AsyncOperation(
3138
channelName = "example-consumer-topic",
3239
description = "Customer uploaded an example payload", // Optional
33-
servers = {"kafka-server"}, // Optional
34-
headers = @AsyncOperation.Headers( // Optional
35-
schemaName = "SpringKafkaDefaultHeaders",
36-
values = {
37-
@AsyncOperation.Headers.Header(
38-
name = DEFAULT_CLASSID_FIELD_NAME,
39-
description = "Spring Type Id Header",
40-
value = "io.github.springwolf.example.dtos.ExamplePayloadDto"
41-
),
42-
// (demonstrating https://cloudevents.io)
43-
@AsyncOperation.Headers.Header(
44-
name = AsyncHeadersCloudEventConstants.TYPE,
45-
description = AsyncHeadersCloudEventConstants.TYPE_DESC,
46-
value = "NestedPayloadDto.v1")
47-
// ...
48-
}
49-
)
40+
servers = {"kafka-server"} // Optional
5041
))
5142
@KafkaAsyncOperationBinding
5243
public void receiveMessage(ExamplePayloadDto msg) {
@@ -66,17 +57,7 @@ The channel name (or topic name in case of Kafka) - this is the name that will b
6657

6758
Optional. The description allows for human-friendly text to verbosely explain the _message_, like specific domain, what the topic is used for and which data it contains.
6859

69-
### Header
70-
71-
Optional. The headers describing the metadata of the payload.
72-
7360
### Servers
7461

7562
Optional. Useful when an application is connect to multiple brokers and wants to indicate to which broker the channel belongs to.
7663
The server name needs to exist in [configuration > Servers](configuration.mdx) as well.
77-
78-
## `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener`
79-
80-
The `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener` annotations are detected automatically.
81-
There is nothing more to do.
82-
Use the other option if the provided documentation is insufficient.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
sidebar_position: 69
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
import CodeBlock from '@theme/CodeBlock';
8+
import CodeSchemaGroovy from '!!raw-loader!./snippets/_schema_groovy.gradle';
9+
import CodeSchemaMaven from '!!raw-loader!./snippets/_schema_maven.xml';
10+
11+
# Headers
12+
13+
Springwolf provides different ways to document headers. The `header` is mapped to an AsyncAPI `schemaObject`.
14+
15+
## Auto-detection
16+
17+
Besides the payload, Springwolf detects the Spring `@Header` annotation within the method signature:
18+
19+
```java
20+
@KafkaListener(topics = "example-topic")
21+
public void receiveExamplePayload(
22+
@Payload ExamplePayloadDto payload, // @Payload is required for multiple parameters
23+
@Header(KafkaHeaders.RECEIVED_KEY) String key,
24+
@Header(KafkaHeaders.OFFSET) Integer offset) {
25+
// process
26+
}
27+
```
28+
29+
## Using `@AsyncOperation.Headers`
30+
31+
Again, the annotation property `headers` of `@AsyncOperation` allows to overwrite the headers, as shown below:
32+
33+
```java
34+
@AsyncPublisher(operation = @AsyncOperation(
35+
channelName = "example-producer-topic",
36+
headers = @AsyncOperation.Headers( // Optional
37+
schemaName = "SpringKafkaDefaultHeaders",
38+
values = {
39+
@AsyncOperation.Headers.Header(
40+
name = DEFAULT_CLASSID_FIELD_NAME,
41+
description = "Spring Type Id Header",
42+
value = "io.github.springwolf.example.dtos.ExamplePayloadDto"
43+
),
44+
// demonstrating https://cloudevents.io
45+
@AsyncOperation.Headers.Header(
46+
name = AsyncHeadersCloudEventConstants.TYPE,
47+
description = AsyncHeadersCloudEventConstants.TYPE_DESC,
48+
value = "ExamplePayloadDto.v1")
49+
// ...
50+
}
51+
)
52+
))
53+
public void sendMessage(ExamplePayloadDto msg) {
54+
// process
55+
}
56+
```
57+
58+
## Schema
59+
60+
Under the hood Springwolf relies on swagger-core `ModelConverters` to define the message schema.
61+
62+
By default, the type and example values for the properties are guessed.
63+
The default Jackson `ModelResolver` supports schema definitions via `@Schema` to overwrite the property definitions.
64+
65+
### Using `@Schema`
66+
67+
The `@Schema` annotation allows to set many properties like `description`, `example`, `requiredMode`, `minimum` to document payloads.
68+
69+
All properties are part of the produced AsyncAPI file. However, not all are displayed in `springwolf-ui` (see [#378](https://github.com/springwolf/springwolf-core/issues/378))
70+
71+
#### Usage
72+
73+
Add the following dependency:
74+
75+
<Tabs>
76+
<TabItem value="Groovy" label="Groovy" default>
77+
<CodeBlock language="groovy">{CodeSchemaGroovy}</CodeBlock>
78+
</TabItem>
79+
<TabItem value="Maven" label="Maven">
80+
<CodeBlock language="xml">{CodeSchemaMaven}</CodeBlock>
81+
</TabItem>
82+
</Tabs>
83+
84+
Then, add the `@Schema` annotation to the payload class:
85+
86+
<!-- vale off -->
87+
```java
88+
import io.swagger.v3.oas.annotations.media.Schema;
89+
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
90+
91+
@Schema(description = "Example payload model")
92+
public class ExamplePayloadDto {
93+
@Schema(description = "Some string field", example = "some string value", requiredMode = REQUIRED)
94+
private String someString;
95+
96+
public String getSomeString() {
97+
return someString;
98+
}
99+
}
100+
```
101+
<!-- vale on -->
102+
103+
:::note
104+
The `@AsyncMessage.description` field will always override the `@Schema` description if provided
105+
:::
106+
107+
For a full example, take a look at [ExamplePayloadDto.java in `springwolf-amqp-example`](https://github.com/springwolf/springwolf-core/blob/master/springwolf-examples/springwolf-amqp-example/src/main/java/io/github/springwolf/examples/amqp/dtos/ExamplePayloadDto.java)
108+
109+
#### Primitive, final and external classes
110+
111+
When the `@Schema` annotation can't be attached to the payload class (that's `java.lang.String`), the payload can be wrapped in an envelope class. The actual payload is a field within this class (`StringEnvelope`), marked using `@AsyncApiPayload` and documented using the `@Schema` annotation.
112+
113+
```java
114+
@AsyncListener( operation = @AsyncOperation( channelName = TOPIC,
115+
payloadType = StringEnvelope.class) // <- envelope class
116+
)
117+
public void receiveStringPayload(String stringPayload) { // <- The original class is used here
118+
// ...
119+
}
120+
121+
@Data
122+
static class StringEnvelope {
123+
@AsyncApiPayload // <- The annotation marker
124+
@Schema(description = "Payload description using @Schema annotation and @AsyncApiPayload within envelope class")
125+
private final String payload;
126+
}
127+
```
128+
129+
:::info
130+
See [Add-Ons](../add-ons) for more information on how to document other formats
131+
:::

docs/configuration/documenting-messages.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import CodeSchemaMaven from '!!raw-loader!./snippets/_schema_maven.xml';
1010

1111
# Messages
1212

13-
Springwolf provides different ways to document the messages. The `message` is part of the AsyncAPI `operationObject`
13+
Springwolf provides different ways to document the messages. The `message` is part of the AsyncAPI `operationObject` and mapped as `messageObject`.
1414

1515
> A definition of the message that will be published or received by this operation
1616
@@ -22,7 +22,7 @@ For example:
2222
@AsyncPublisher(operation = @AsyncOperation(
2323
channelName = "example-producer-topic",
2424
description = "Customer uploaded an example payload", // Optional
25-
payloadType = ExamplePayloadDto.class, // Optional
25+
payloadType = ExamplePayloadDto.class, // Optional. Overwrites the detected payload
2626
message = @AsyncMessage( // Optional
2727
messageId = "my-unique-id",
2828
name = "ExamplePayloadDto",

docs/configuration/documenting-producers.md

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,7 @@ Below is an example to demonstrate the annotation:
2424
@AsyncPublisher(operation = @AsyncOperation(
2525
channelName = "example-producer-topic",
2626
description = "Customer uploaded an example payload", // Optional
27-
servers = {"kafka-server"}, // Optional
28-
headers = @AsyncOperation.Headers( // Optional
29-
schemaName = "SpringKafkaDefaultHeaders",
30-
values = {
31-
@AsyncOperation.Headers.Header(
32-
name = DEFAULT_CLASSID_FIELD_NAME,
33-
description = "Spring Type Id Header",
34-
value = "io.github.springwolf.example.dtos.ExamplePayloadDto"
35-
),
36-
// (demonstrating https://cloudevents.io)
37-
@AsyncOperation.Headers.Header(
38-
name = AsyncHeadersCloudEventConstants.TYPE,
39-
description = AsyncHeadersCloudEventConstants.TYPE_DESC,
40-
value = "NestedPayloadDto.v1")
41-
// ...
42-
}
43-
)
27+
servers = {"kafka-server"} // Optional
4428
))
4529
@KafkaAsyncOperationBinding
4630
public void sendMessage(ExamplePayloadDto msg) {
@@ -60,10 +44,6 @@ The channel name (or topic name in case of Kafka) - this is the name that will b
6044

6145
Optional. The description allows for human-friendly text to verbosely explain the _message_, like specific domain, what the topic is used for and which data it contains.
6246

63-
### Header
64-
65-
Optional. The headers describing the metadata of the payload.
66-
6747
### Servers
6848

6949
Optional. Useful when an application is connect to multiple brokers and wants to indicate to which broker the channel belongs to.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
dependencies {
2-
implementation 'io.swagger.core.v3:swagger-core:2.2.20'
2+
implementation 'io.swagger.core.v3:swagger-core:2.2.22'
33
}

0 commit comments

Comments
 (0)