Skip to content

Commit c8d333d

Browse files
authored
feat(kafka): demonstrate cloud event headers in example (#426)
* feat(kafka): demonstrate cloud event headers in example * feat(kafka): rename schema to SpringDefaultHeaderAndCloudEvent
1 parent 6aa38ba commit c8d333d

File tree

5 files changed

+151
-13
lines changed

5 files changed

+151
-13
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
String name();
6060

6161
/**
62-
* Mapped to {@link AsyncHeaderSchema#getDescription()} ()}
62+
* Mapped to {@link AsyncHeaderSchema#getDescription()}
6363
*/
6464
String description() default "";
6565

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
package io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header;
3+
4+
public class AsyncHeadersCloudEventConstants {
5+
public static final String CONTENT_TYPE = "content-type";
6+
public static final String CONTENT_TYPE_DESC = "CloudEvent Content-Type Header";
7+
public static final String ID = "ce_id";
8+
public static final String ID_DESC = "CloudEvent Id Header";
9+
public static final String SPECVERSION = "ce_specversion";
10+
public static final String SPECVERSION_DESC = "CloudEvent Spec Version Header";
11+
public static final String SOURCE = "ce_source";
12+
public static final String SOURCE_DESC = "CloudEvent Source Header";
13+
public static final String SUBJECT = "ce_subject";
14+
public static final String SUBJECT_DESC = "CloudEvent Subject Header";
15+
public static final String TIME = "ce_time";
16+
public static final String TIME_DESC = "CloudEvent Time Header";
17+
public static final String TYPE = "ce_type";
18+
public static final String TYPE_DESC = "CloudEvent Payload Type Header";
19+
}

springwolf-core/src/main/java/io/github/stavshamir/springwolf/asyncapi/types/channel/operation/message/header/AsyncHeadersForCloudEventsBuilder.java

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
import java.util.List;
88

9+
/**
10+
* Only used in combination with AsyncApiDocket bean
11+
* If not, let us know by raising a GitHub issue
12+
*/
13+
@Deprecated
914
public class AsyncHeadersForCloudEventsBuilder {
1015

1116
private final AsyncHeaders headers;
@@ -31,58 +36,79 @@ public AsyncHeadersForCloudEventsBuilder withContentTypeHeader(
3136
List<String> contentTypeStringValues =
3237
contentTypeValues.stream().map(MimeType::toString).toList();
3338
return withHeader(
34-
"content-type",
39+
AsyncHeadersCloudEventConstants.CONTENT_TYPE,
3540
contentTypeStringValues,
3641
exampleContentType.toString(),
37-
"CloudEvent Content-Type Header");
42+
AsyncHeadersCloudEventConstants.CONTENT_TYPE_DESC);
3843
}
3944

4045
public AsyncHeadersForCloudEventsBuilder withSpecVersionHeader(String specVersion) {
4146
return withSpecVersionHeader(specVersion, List.of(specVersion));
4247
}
4348

4449
public AsyncHeadersForCloudEventsBuilder withSpecVersionHeader(String specVersion, List<String> specValues) {
45-
return withHeader("ce_specversion", specValues, specVersion, "CloudEvent Spec Version Header");
50+
return withHeader(
51+
AsyncHeadersCloudEventConstants.SPECVERSION,
52+
specValues,
53+
specVersion,
54+
AsyncHeadersCloudEventConstants.SPECVERSION_DESC);
4655
}
4756

4857
public AsyncHeadersForCloudEventsBuilder withIdHeader(String idExample) {
4958
return withIdHeader(idExample, List.of(idExample));
5059
}
5160

5261
public AsyncHeadersForCloudEventsBuilder withIdHeader(String idExample, List<String> idValues) {
53-
return withHeader("ce_id", idValues, idExample, "CloudEvent Id Header");
62+
return withHeader(
63+
AsyncHeadersCloudEventConstants.ID, idValues, idExample, AsyncHeadersCloudEventConstants.ID_DESC);
5464
}
5565

5666
public AsyncHeadersForCloudEventsBuilder withTimeHeader(String timeExample) {
5767
return withTimeHeader(timeExample, List.of(timeExample));
5868
}
5969

6070
public AsyncHeadersForCloudEventsBuilder withTimeHeader(String timeExample, List<String> timeValues) {
61-
return withHeader("ce_time", timeValues, timeExample, "CloudEvent Time Header");
71+
return withHeader(
72+
AsyncHeadersCloudEventConstants.TIME,
73+
timeValues,
74+
timeExample,
75+
AsyncHeadersCloudEventConstants.TIME_DESC);
6276
}
6377

6478
public AsyncHeadersForCloudEventsBuilder withTypeHeader(String typeExample) {
6579
return withTypeHeader(typeExample, List.of(typeExample));
6680
}
6781

6882
public AsyncHeadersForCloudEventsBuilder withTypeHeader(String typeExample, List<String> typeValues) {
69-
return withHeader("ce_type", typeValues, typeExample, "CloudEvent Payload Type Header");
83+
return withHeader(
84+
AsyncHeadersCloudEventConstants.TYPE,
85+
typeValues,
86+
typeExample,
87+
AsyncHeadersCloudEventConstants.TYPE_DESC);
7088
}
7189

7290
public AsyncHeadersForCloudEventsBuilder withSourceHeader(String sourceExample) {
7391
return withSourceHeader(sourceExample, List.of(sourceExample));
7492
}
7593

7694
public AsyncHeadersForCloudEventsBuilder withSourceHeader(String sourceExample, List<String> sourceValues) {
77-
return withHeader("ce_source", sourceValues, sourceExample, "CloudEvent Source Header");
95+
return withHeader(
96+
AsyncHeadersCloudEventConstants.SOURCE,
97+
sourceValues,
98+
sourceExample,
99+
AsyncHeadersCloudEventConstants.SOURCE_DESC);
78100
}
79101

80102
public AsyncHeadersForCloudEventsBuilder withSubjectHeader(String subjectExample) {
81103
return withSubjectHeader(subjectExample, List.of(subjectExample));
82104
}
83105

84106
public AsyncHeadersForCloudEventsBuilder withSubjectHeader(String subjectExample, List<String> subjectValues) {
85-
return withHeader("ce_subject", subjectValues, subjectExample, "CloudEvent Subject Header");
107+
return withHeader(
108+
AsyncHeadersCloudEventConstants.SUBJECT,
109+
subjectValues,
110+
subjectExample,
111+
AsyncHeadersCloudEventConstants.SUBJECT_DESC);
86112
}
87113

88114
public AsyncHeadersForCloudEventsBuilder withExtension(

springwolf-examples/springwolf-kafka-example/src/main/java/io/github/stavshamir/springwolf/example/kafka/producers/NestedProducer.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.KafkaAsyncOperationBinding;
77
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.KafkaAsyncOperationBinding.KafkaAsyncKey;
88
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.KafkaAsyncOperationBinding.KafkaAsyncMessageBinding;
9+
import io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.header.AsyncHeadersCloudEventConstants;
910
import io.github.stavshamir.springwolf.example.kafka.configuration.KafkaConfiguration;
1011
import io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto;
1112
import org.springframework.beans.factory.annotation.Autowired;
13+
import org.springframework.http.MediaType;
1214
import org.springframework.kafka.core.KafkaTemplate;
1315
import org.springframework.stereotype.Component;
1416

@@ -27,13 +29,41 @@ public class NestedProducer {
2729
description = "Custom, optional description defined in the AsyncPublisher annotation",
2830
headers =
2931
@AsyncOperation.Headers(
30-
schemaName = "SpringKafkaDefaultHeaders",
32+
schemaName = "SpringDefaultHeaderAndCloudEvent",
3133
values = {
3234
@AsyncOperation.Headers.Header(
3335
name = DEFAULT_CLASSID_FIELD_NAME,
3436
description = "Spring Type Id Header",
3537
value =
3638
"io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto"),
39+
@AsyncOperation.Headers.Header(
40+
name = AsyncHeadersCloudEventConstants.CONTENT_TYPE,
41+
description = AsyncHeadersCloudEventConstants.CONTENT_TYPE_DESC,
42+
value = MediaType.APPLICATION_JSON_VALUE),
43+
@AsyncOperation.Headers.Header(
44+
name = AsyncHeadersCloudEventConstants.ID,
45+
description = AsyncHeadersCloudEventConstants.ID_DESC,
46+
value = "2c60089e-6f39-459d-8ced-2d6df7e4c03a"),
47+
@AsyncOperation.Headers.Header(
48+
name = AsyncHeadersCloudEventConstants.SPECVERSION,
49+
description = AsyncHeadersCloudEventConstants.SPECVERSION_DESC,
50+
value = "1.0"),
51+
@AsyncOperation.Headers.Header(
52+
name = AsyncHeadersCloudEventConstants.SOURCE,
53+
description = AsyncHeadersCloudEventConstants.SOURCE_DESC,
54+
value = "http://localhost"),
55+
@AsyncOperation.Headers.Header(
56+
name = AsyncHeadersCloudEventConstants.SUBJECT,
57+
description = AsyncHeadersCloudEventConstants.SUBJECT_DESC,
58+
value = "${spring.application.name}"),
59+
@AsyncOperation.Headers.Header(
60+
name = AsyncHeadersCloudEventConstants.TIME,
61+
description = AsyncHeadersCloudEventConstants.TIME_DESC,
62+
value = "2023-10-28 20:01:23+00:00"),
63+
@AsyncOperation.Headers.Header(
64+
name = AsyncHeadersCloudEventConstants.TYPE,
65+
description = AsyncHeadersCloudEventConstants.TYPE_DESC,
66+
value = "NestedPayloadDto.v1"),
3767
})))
3868
@KafkaAsyncOperationBinding(
3969
clientId = "foo-clientId",

springwolf-examples/springwolf-kafka-example/src/test/resources/asyncapi.json

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@
261261
"$ref": "#/components/schemas/io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto"
262262
},
263263
"headers": {
264-
"$ref": "#/components/schemas/SpringKafkaDefaultHeaders"
264+
"$ref": "#/components/schemas/SpringDefaultHeaderAndCloudEvent"
265265
},
266266
"bindings": {
267267
"kafka": {
@@ -354,7 +354,7 @@
354354
"properties": { },
355355
"example": { }
356356
},
357-
"SpringKafkaDefaultHeaders": {
357+
"SpringDefaultHeaderAndCloudEvent": {
358358
"type": "object",
359359
"properties": {
360360
"__TypeId__": {
@@ -364,10 +364,73 @@
364364
"enum": [
365365
"io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto"
366366
]
367+
},
368+
"ce_id": {
369+
"type": "string",
370+
"description": "CloudEvent Id Header",
371+
"example": "2c60089e-6f39-459d-8ced-2d6df7e4c03a",
372+
"enum": [
373+
"2c60089e-6f39-459d-8ced-2d6df7e4c03a"
374+
]
375+
},
376+
"ce_source": {
377+
"type": "string",
378+
"description": "CloudEvent Source Header",
379+
"example": "http://localhost",
380+
"enum": [
381+
"http://localhost"
382+
]
383+
},
384+
"ce_specversion": {
385+
"type": "string",
386+
"description": "CloudEvent Spec Version Header",
387+
"example": "1.0",
388+
"enum": [
389+
"1.0"
390+
]
391+
},
392+
"ce_subject": {
393+
"type": "string",
394+
"description": "CloudEvent Subject Header",
395+
"example": "Springwolf example project - Kafka",
396+
"enum": [
397+
"Springwolf example project - Kafka"
398+
]
399+
},
400+
"ce_time": {
401+
"type": "string",
402+
"description": "CloudEvent Time Header",
403+
"example": "2023-10-28 20:01:23+00:00",
404+
"enum": [
405+
"2023-10-28 20:01:23+00:00"
406+
]
407+
},
408+
"ce_type": {
409+
"type": "string",
410+
"description": "CloudEvent Payload Type Header",
411+
"example": "NestedPayloadDto.v1",
412+
"enum": [
413+
"NestedPayloadDto.v1"
414+
]
415+
},
416+
"content-type": {
417+
"type": "string",
418+
"description": "CloudEvent Content-Type Header",
419+
"example": "application/json",
420+
"enum": [
421+
"application/json"
422+
]
367423
}
368424
},
369425
"example": {
370-
"__TypeId__": "io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto"
426+
"__TypeId__": "io.github.stavshamir.springwolf.example.kafka.dtos.NestedPayloadDto",
427+
"ce_id": "2c60089e-6f39-459d-8ced-2d6df7e4c03a",
428+
"ce_source": "http://localhost",
429+
"ce_specversion": "1.0",
430+
"ce_subject": "Springwolf example project - Kafka",
431+
"ce_time": "2023-10-28 20:01:23+00:00",
432+
"ce_type": "NestedPayloadDto.v1",
433+
"content-type": "application/json"
371434
}
372435
},
373436
"SpringKafkaDefaultHeaders-AnotherPayloadDto": {

0 commit comments

Comments
 (0)