Skip to content

Commit a9f8ca6

Browse files
authored
docs: update docs for 0.17.0 release (#65)
1 parent 2cdd1a1 commit a9f8ca6

File tree

11 files changed

+234
-162
lines changed

11 files changed

+234
-162
lines changed

docs/behind-the-scenes.md

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

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

docs/configuration/configuration.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ There are 2 ways to configure Springwolf which can't be combined:
3131

3232
It's recommended to structure the project such that all consumers and producers (classes containing listener/producer methods) are in the same package - it's not mandatory, and if they're scattered across multiple packages, just provide the highest in hierarchy package that contains all classes.
3333

34-
The base package will be scanned for classes containing `@Component` annotated classes (that includes `@Service` annotated classes) for methods annotated with `@KafkaListener`, `@RabbitListener`, `@SqsListener`, `@AsyncListener`, `@AsyncPublisher`, etc.
34+
The base package will be scanned for classes containing `@Component` annotated classes (that includes `@Service` annotated classes) for methods annotated with `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener`, `@AsyncListener`, `@AsyncPublisher`, etc.
3535

3636
### `id`
3737

@@ -47,9 +47,9 @@ The `Info` object provides metadata about the API (see [Info Object][info]).
4747

4848
All provided fields will be present in the generated document, but not all will be displayed in the UI.
4949

50-
### `Server`
50+
### `Servers`
5151

52-
The `Server` object provides metadata the can help the reader understand the protocol, version, login details and more (see [Server Object][server]).
52+
The `Server` object provides metadata to help the reader understand the protocol, version, login details and more (see [AsyncAPI Server Object][server]).
5353

5454
An AsyncAPI document can contain more than one server, but it's not common.
5555

@@ -75,13 +75,17 @@ The following table contains additional properties that can be specified in the
7575
| `springwolf.paths.docs` | `/springwolf/docs` | The path of the AsyncAPI document in JSON format. *Note that at the moment the UI will work only with the default value.* |
7676
| `springwolf.endpoint.actuator.enabled` | `false` | Publish the AsyncAPI document as part of Spring Boot’s actuator feature. |
7777
| `springwolf.use-fqn` | `false` | Use fully qualified names for the schema classes. It's recommended and **required for publishing**, but deactivated due to backwards compatibility |
78+
| `springwolf.payload.extractable-classes..` | N/A | Extract additional payload types. See [message payloads](documenting-messages.md) for more details. |
7879
| `springwolf.scanner.consumer-data.enabled` | `true` | Enable scanner to find consumers defined in `AsyncApiDocket`. |
7980
| `springwolf.scanner.producer-data.enabled` | `true` | Enable scanner to find producers defined in `AsyncApiDocket`. |
8081
| `springwolf.scanner.async-listener.enabled` | `true` | Enable scanner to find methods annotated with `@AsyncListener`. |
8182
| `springwolf.scanner.async-publisher.enabled` | `true` | Enable scanner to find methods annotated with `@AsyncPublisher`. |
8283
| **AMQP** | | |
8384
| `springwolf.plugin.amqp.publishing.enabled` | `false` | Allow (anyone) to produce AMQP messages from the UI. *Note that this has security implications* |
8485
| `springwolf.plugin.amqp.scanner.rabbit-listener.enabled` | `true` | Enable scanner to find methods annotated with `@RabbitListener`. |
86+
| **JMS** | | |
87+
| `springwolf.plugin.jms.publishing.enabled` | `false` | Allow (anyone) to produce JMS messages from the UI. *Note that this has security implications* |
88+
| `springwolf.plugin.jms.scanner.jms-listener.enabled` | `true` | Enable scanner to find methods annotated with `@JmsListener`. |
8589
| **Kafka** | | |
8690
| `springwolf.plugin.kafka.publishing.enabled` | `false` | Allow (anyone) to produce Kafka messages from the UI. *Note that this has security implications* |
8791
| `springwolf.plugin.kafka.publishing.producer` | `null` | Configure the Kafka producer used to publish messages from the UI. Uses identical parameters as `spring.kafka.producer` |
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
sidebar_position: 66
3+
---
4+
5+
# Bindings
6+
7+
To indicate the binding (protocol) that's documented, there are multiple options to document them.
8+
Add at least one binding so that readers know the protocol in use and functionality like publishing works.
9+
10+
To use the protocol specific bindings, ensure that you have added the corresponding [plugin](../introduction/supported-protocols.md).
11+
12+
## Option 1: Annotations
13+
14+
### `@AmqpAsyncOperationBinding`
15+
16+
Associate this operation with AMQP, see [operation-binding] for details.
17+
18+
```java
19+
@AmqpAsyncOperationBinding(cc = "example-topic-routing-key")
20+
```
21+
22+
### `@KafkaAsyncOperationBinding`
23+
24+
Associate this operation with Kafka, see [operation-binding] for details.
25+
26+
```java
27+
@KafkaAsyncOperationBinding(
28+
bindingVersion = "1"
29+
)
30+
```
31+
32+
### `@JmsAsyncOperationBinding`
33+
34+
Associate this operation with JMS, see [operation-binding] for details.
35+
36+
```java
37+
@JmsAsyncOperationBinding
38+
```
39+
40+
### `@SnsAsyncOperationBinding`
41+
42+
Associate this operation with SNS, see [operation-binding] for details.
43+
```java
44+
@SnsAsyncOperationBinding
45+
```
46+
47+
### `@SqsAsyncOperationBinding`
48+
49+
Associate this operation with SQS, see [operation-binding] for details.
50+
51+
```java
52+
@SqsAsyncOperationBinding
53+
```
54+
55+
### `@AsyncGenericOperationBinding`
56+
57+
This binding is generic, so that any properties can be specified.
58+
You can define anything and there is no validation.
59+
60+
```java
61+
@AsyncGenericOperationBinding(
62+
type = "custom-binding",
63+
fields = {
64+
"internal-field=customValue",
65+
"nested.key=nestedValue"
66+
}
67+
)
68+
```
69+
70+
## Option 2: AsyncApiDocket (deprecated)
71+
72+
### `AmqpProducerData` / `AmqpConsumerData`
73+
74+
```java
75+
AmqpProducerData exampleProducer = AmqpProducerData.amqpProducerDataBuilder()
76+
.queueName("example-producer-channel")
77+
.description("example-producer-channel-description")
78+
.exchangeName("example-topic-exchange")
79+
.routingKey("example-topic-routing-key")
80+
.payloadType(AnotherPayloadDto.class)
81+
.build();
82+
```
83+
84+
### `KafkaProducerData` / `KafkaConsumeData`
85+
86+
```java
87+
KafkaProducerData exampleProducerData = KafkaProducerData.kafkaProducerDataBuilder()
88+
.topicName("example-producer-topic")
89+
.description("Optional. Customer uploaded an example payload")
90+
.payloadType(ExamplePayloadDto.class)
91+
.headers(AsyncHeaders.NOT_USED)
92+
.build();
93+
```
94+
95+
## Binding properties
96+
Explanation of the different binding properties.
97+
98+
### General
99+
The following properties are the same for all bindings.
100+
101+
#### Queue Name (Channel Name)
102+
103+
The queue name that will be used to publish messages to by the UI.
104+
105+
#### Description
106+
107+
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.
108+
109+
#### Payload Type
110+
111+
The class object of the payload that will be published to this channel.
112+
113+
#### Headers
114+
115+
The Kafka headers describing the metadata of the payload, more details in the generic ProducerData.
116+
117+
The Springwolf comes with a special `AsyncHeadersCloudEventConstants` to document CloudEvents.
118+
119+
The `kafka` header `__TypeId__` (constant from ` AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME`) can be documented as well.
120+
121+
### AMQP
122+
123+
#### Exchange Name
124+
125+
The exchange name that will be used to bind queues to.
126+
127+
#### Routing Key
128+
129+
The routing key used when publishing a message.
130+
131+
132+
### Kafka
133+
134+
#### Group Id
135+
The group id that will be used during message consumption
136+
137+
#### Client Id
138+
The client id to identify the consumer
139+
140+
[operation-binding]: https://www.asyncapi.com/docs/reference/specification/v2.6.0#operationBindingsObject

docs/configuration/documenting-consumers.md

Lines changed: 14 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ For these use-cases, Springwolf provides additional ways to explicitly add them
1212
To document consumers, either:
1313
- add the `@AsyncListener` annotation or
1414
- (deprecated) declare the `ConsumerData` object as part of the `AsyncApiDocket` or
15-
- rely on the auto-detection of `@KafkaListener`, `@RabbitListener`, `@SqsListener`
15+
- rely on the auto-detection of `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener`
1616

1717
You are free to use all options together. Per channel and operation, first `ConsumerData` is used, then `@AsyncListener` and last the auto-detected annotations.
1818

@@ -29,6 +29,7 @@ Below is an example to demonstrate the annotation:
2929
@AsyncListener(operation = @AsyncOperation(
3030
channelName = "example-consumer-topic",
3131
description = "Optional. Customer uploaded an example payload",
32+
servers = {"kafka"},
3233
headers = @AsyncOperation.Headers(
3334
schemaName = "SpringKafkaDefaultHeaders",
3435
values = {
@@ -37,6 +38,12 @@ Below is an example to demonstrate the annotation:
3738
description = "Spring Type Id Header",
3839
value = "io.github.stavshamir.springwolf.example.dtos.ExamplePayloadDto"
3940
),
41+
// (demonstrating https://cloudevents.io)
42+
@AsyncOperation.Headers.Header(
43+
name = AsyncHeadersCloudEventConstants.TYPE,
44+
description = AsyncHeadersCloudEventConstants.TYPE_DESC,
45+
value = "NestedPayloadDto.v1")
46+
// ...
4047
}
4148
)
4249
))
@@ -58,34 +65,14 @@ The channel name (or topic name in case of Kafka) - this is the name that will b
5865

5966
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.
6067

61-
### Payload Type
62-
63-
The class object of the payload that will be consumed from this channel.
64-
If not specified, it's extracted from the method arguments.
65-
6668
### Header
6769

6870
Optional. The headers describing the metadata of the payload.
6971

70-
### `@AmqpAsyncOperationBinding`
71-
72-
Associate this operation with AMQP, see [operation-binding] for details.
72+
### Servers
7373

74-
```java
75-
@AmqpAsyncOperationBinding(cc = "example-topic-routing-key")
76-
```
77-
78-
### `@KafkaAsyncOperationBinding`
79-
80-
Associate this operation with Kafka, see [operation-binding] for details.
81-
82-
```java
83-
@KafkaAsyncOperationBinding(
84-
bindingVersion = "1",
85-
clientId = "foo-clientId",
86-
groupId = "#{'foo-groupId'}"
87-
)
88-
```
74+
Optional. Useful when an application is connect to multiple brokers and wants to indicate to which broker the channel belongs to.
75+
The server needs to exist in [configuration > Servers](configuration.md) as well.
8976

9077

9178
## Option 2: `ConsumerData` (deprecated)
@@ -133,7 +120,7 @@ Optional. The description allows for human-friendly text to verbosely explain th
133120

134121
### Binding
135122

136-
This property is used to discriminate the producer's protocol and provide protocol-specific properties (see [operation-binding])).
123+
This property is used to discriminate the producer's protocol and provide protocol-specific properties (see [documenting bindings](documenting-bindings.md)).
137124

138125
### Payload Type
139126

@@ -172,58 +159,7 @@ The above Kafka `ConsumerData` simplifies to the following `KafkaConsumerData`:
172159
```
173160

174161

175-
## Option 3: `@KafkaListener`, `@RabbitListener`, `@SqsListener`
176-
The `@KafkaListener`, `@RabbitListener`, `@SqsListener` annotations are detected automatically.
162+
## Option 3: `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener`
163+
The `@JmsListener`, `@KafkaListener`, `@RabbitListener`, `@SqsListener` annotations are detected automatically.
177164
There is nothing more to do.
178165
Use the other options if the provided documentation is insufficient.
179-
180-
181-
## AMQP Parameters
182-
### Queue Name (Channel Name)
183-
184-
The queue name that will be used to consume messages from.
185-
186-
### Description
187-
188-
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.
189-
190-
### Exchange Name
191-
192-
The exchange name that will be used to bind queues to.
193-
194-
### Routing Key
195-
196-
The routing key used when publishing a message.
197-
198-
### Payload Type
199-
200-
The class object of the payload that will be consumed from this channel.
201-
202-
203-
## Kafka Parameters
204-
205-
### Topic Name (Channel Name)
206-
207-
The topic name that will be used to consume messages from.
208-
209-
### Description
210-
211-
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.
212-
213-
### Payload Type
214-
215-
The class object of the payload that will be consumed from this channel.
216-
217-
### Headers
218-
219-
The Kafka headers describing the metadata of the payload, more details in the generic ConsumerData.
220-
221-
The Springwolf Kafka plugin comes with a special `AsyncHeadersForSpringKafkaBuilder` to document the `__TypeId__` header of the `spring-kafka` dependency.
222-
223-
## Examples
224-
225-
- [AMQP Example](https://github.com/springwolf/springwolf-core/blob/master/springwolf-examples/springwolf-amqp-example/src/main/java/io/github/stavshamir/springwolf/example/amqp/configuration/AsyncApiConfiguration.java)
226-
- [Cloud Stream Example](https://github.com/springwolf/springwolf-core/blob/master/springwolf-examples/springwolf-cloud-stream-example/src/main/java/io/github/stavshamir/springwolf/example/cloudstream/configuration/AsyncApiConfiguration.java)
227-
- [Kafka Example](https://github.com/springwolf/springwolf-core/blob/master/springwolf-examples/springwolf-kafka-example/src/main/java/io/github/stavshamir/springwolf/example/kafka/configuration/AsyncApiConfiguration.java)
228-
229-
[operation-binding]: https://www.asyncapi.com/docs/reference/specification/v2.0.0#operationBindingsObject

docs/configuration/documenting-messages.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ For example:
2121
@AsyncPublisher(operation = @AsyncOperation(
2222
channelName = "example-producer-topic",
2323
description = "Optional. Customer uploaded an example payload",
24+
payloadType = ExamplePayloadDto.class, // optional
2425
message = @AsyncMessage(
2526
messageId = "my-unique-id",
2627
name = "ExamplePayloadDto",
@@ -33,14 +34,43 @@ public void sendMessage(ExamplePayloadDto msg) {
3334
}
3435
```
3536

37+
## Payload Type
38+
39+
Springwolf tries to auto-detect the payload type based on the method signature.
40+
41+
When the method has multiple arguments, the payload can be indicated via `@Payload`, i.e.
42+
```java
43+
public void sendMessage(@Payload ExamplePayloadDto msg, String traceId, Object loggingContext) {}
44+
```
45+
46+
Alternatively, the annotation property `payloadType` of `@AsyncOperation` allows to overwrite the detected class.
47+
48+
### Unwrapping the Payload
49+
50+
Sometimes, the payload type is wrapped in other objects.
51+
Some wrappers are automatically unwrapped, including `Message<String>`, which becomes `String`.
52+
53+
:::note
54+
The [configuration property](configuration.md) to modify the defaults is currently in _beta_.
55+
:::
56+
57+
Assuming a method signature of `sendMessage(Function<Void, String> msg)`, where the actual payload is located in parameter index 1 (String).
58+
Adding the configuration property `springwolf.payload.extractable-classes.java.util.function.Function=1` tells Springwolf how to handle this payload type.
59+
60+
The configuration property is split into three parts.
61+
First, the base property `springwolf.payload.extractable-classes`.
62+
Second, the canonical class name, `java.util.function.Function` in this case.
63+
And third, the generic parameter index (`1`).
64+
65+
3666
## Schema
3767

3868
Under the hood Springwolf relies on swagger-core `ModelConverters` to define the message schema.
3969

4070
By default, the type and example values for the properties are guessed.
4171
The default Jackson `ModelResolver` supports schema definitions via `@Schema` to overwrite the property definitions.
4272

43-
## Using `@Schema`
73+
### Using `@Schema`
4474

4575
The `@Schema` annotation allows to set many properties like `description`, `example`, `requiredMode` to document payloads.
4676

@@ -84,6 +114,10 @@ The `@AsyncMessage.description` field will always override the `@Schema` descrip
84114

85115
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/stavshamir/springwolf/example/amqp/dtos/ExamplePayloadDto.java)
86116

117+
### `json-schema`
118+
119+
The [`springwolf-add-ons/springwolf-json-schema`](https://github.com/springwolf/springwolf-core/tree/master/springwolf-add-ons/springwolf-json-schema) adds the [json-schema](https://json-schema.org) schema to the AsyncApi document.
120+
87121
## Custom ModelConverters
88122

89123
Additionally, custom `ModelConverters` are supported.

0 commit comments

Comments
 (0)