Skip to content

feat(kafka): New Kafka utility #1898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Jun 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9900ab3
Add initial code for KafkaJson and KafkaAvro request handlers.
phipag May 15, 2025
47cbc76
Add deserialization via @Deserialization annotation.
phipag May 16, 2025
680b979
Add TODOs in code.
phipag May 16, 2025
15f2923
Fix typos and make AbstractKafkaDeserializer package private.
phipag May 16, 2025
7c4bf30
Merge phipag/kafka-event from public repository into feature/kafka
phipag May 21, 2025
6ac583f
Remove request handler implementation in favor for @Deserialization a…
phipag May 21, 2025
92ae6ab
Parse Timestamp type correctly.
phipag May 21, 2025
8e13dd6
Remove custom RequestHandler implementation example.
phipag May 21, 2025
623585a
Merge branch 'main' into feature/kafka
phipag May 26, 2025
5ea6d49
Make AspectJ version compatible with min version Java 11.
phipag May 26, 2025
73e64e4
Clarify exception message when deserialization fails.
phipag May 27, 2025
cbe9181
Add more advanced JSON escpaing to JSONSerializer in logging module.
phipag May 27, 2025
64e7080
Add protobuf deserialization logic and fully working example.
phipag May 27, 2025
f081424
Add Maven profile to compile a JAR with different dependency combinat…
phipag May 27, 2025
e11db9a
Add minimal kafka example.
phipag May 28, 2025
4282a77
Add missing copyright.
phipag May 28, 2025
64f7e18
Add unit tests for kafka utility.
phipag May 28, 2025
1191c56
Add minimal kafka example to examples module in pom.xml.
phipag May 29, 2025
db9b989
Add some comments.
phipag May 29, 2025
b64dcbd
Update powertools-examples-kafka with README and make it more minimal…
phipag Jun 6, 2025
4624c12
Implement PR feedback from Karthik.
phipag Jun 6, 2025
598cc27
Fix SAM outputs.
phipag Jun 6, 2025
92f6f8f
Do not fail on unknown properties when deserializating into KafkaEvent.
phipag Jun 6, 2025
7fcc989
Merge branch 'main' into feature/kafka
phipag Jun 16, 2025
77845af
Allow customers to bring their own kafka-clients dependency.
phipag Jun 16, 2025
e4875d8
Add Kafka utility documentation.
phipag Jun 16, 2025
767109b
Update project version consistently to 2.0.0.
phipag Jun 16, 2025
3e6a8b7
fix: Fix bug where abbreviated _HANDLER env var did not detect the De…
phipag Jun 17, 2025
ef04849
fix: Bug when trying to deserialize a type into itself for Lambda def…
phipag Jun 17, 2025
6da89a3
When falling back to Lambda default, handle conversion between InputS…
phipag Jun 17, 2025
2be14dd
Raise a runtime exception when the KafkaEvent is invalid.
phipag Jun 17, 2025
04cf14a
docs: Announce deprecation of v1
phipag Jun 16, 2025
f02c8fd
fix(metrics): Do not flush when no metrics were added to avoid printi…
phipag Jun 16, 2025
fa29f60
Merge branch 'main' into feature/kafka
phipag Jun 18, 2025
3c76357
Rename docs to Kafka Consumer and add line highlights for code examples.
phipag Jun 18, 2025
ffebe8c
Fix Spotbug issues.
phipag Jun 18, 2025
55c860a
Reduce cognitive complexity of DeserializationUtils making it more mo…
phipag Jun 18, 2025
03e5b11
Reduce cognitive complexity of AbstractKafkaDeserializer.
phipag Jun 18, 2025
a5689e9
Enable removal policy DESTROY on e2e test for kinesis streams and SQS…
phipag Jun 18, 2025
8f12c04
Replace System.out with Powertools Logging.
phipag Jun 18, 2025
335279e
Add notice about kafka-clients compatibility.
phipag Jun 18, 2025
e9654a9
Add sentence stating that Avro / Protobuf classes can be autogenerated.
phipag Jun 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,001 changes: 1,001 additions & 0 deletions docs/utilities/kafka.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<module>powertools-examples-parameters/sam</module>
<module>powertools-examples-parameters/sam-graalvm</module>
<module>powertools-examples-serialization</module>
<module>powertools-examples-kafka</module>
<module>powertools-examples-batch</module>
<module>powertools-examples-validation</module>
<module>powertools-examples-cloudformation</module>
Expand All @@ -58,4 +59,4 @@
</plugins>
</build>

</project>
</project>
77 changes: 77 additions & 0 deletions examples/powertools-examples-kafka/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Powertools for AWS Lambda (Java) - Kafka Example

This project demonstrates how to use Powertools for AWS Lambda (Java) to deserialize Kafka Lambda events directly into strongly typed Kafka ConsumerRecords<K, V> using different serialization formats.

## Overview

The example showcases automatic deserialization of Kafka Lambda events into ConsumerRecords using three formats:
- JSON - Using standard JSON serialization
- Avro - Using Apache Avro schema-based serialization
- Protobuf - Using Google Protocol Buffers serialization

Each format has its own Lambda function handler that demonstrates how to use the `@Deserialization` annotation with the appropriate `DeserializationType`, eliminating the need to handle complex deserialization logic manually.

## Build and Deploy

### Prerequisites
- [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
- Java 11+
- Maven

### Build

```bash
# Build the application
sam build
```

### Deploy

```bash
# Deploy the application to AWS
sam deploy --guided
```

During the guided deployment, you'll be prompted to provide values for required parameters. After deployment, SAM will output the ARNs of the deployed Lambda functions.

### Build with Different Serialization Formats

The project includes Maven profiles to build with different serialization formats:

```bash
# Build with JSON only (no Avro or Protobuf)
mvn clean package -P base

# Build with Avro only
mvn clean package -P avro-only

# Build with Protobuf only
mvn clean package -P protobuf-only

# Build with all formats (default)
mvn clean package -P full
```

## Testing

The `events` directory contains sample events for each serialization format:
- `kafka-json-event.json` - Sample event with JSON-serialized products
- `kafka-avro-event.json` - Sample event with Avro-serialized products
- `kafka-protobuf-event.json` - Sample event with Protobuf-serialized products

You can use these events to test the Lambda functions:

```bash
# Test the JSON deserialization function
sam local invoke JsonDeserializationFunction --event events/kafka-json-event.json

# Test the Avro deserialization function
sam local invoke AvroDeserializationFunction --event events/kafka-avro-event.json

# Test the Protobuf deserialization function
sam local invoke ProtobufDeserializationFunction --event events/kafka-protobuf-event.json
```

## Sample Generator Tool

The project includes a tool to generate sample JSON, Avro, and Protobuf serialized data. See the [tools/README.md](tools/README.md) for more information.
51 changes: 51 additions & 0 deletions examples/powertools-examples-kafka/events/kafka-avro-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"eventSource": "aws:kafka",
"eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4",
"bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
"records": {
"mytopic-0": [
{
"topic": "mytopic",
"partition": 0,
"offset": 15,
"timestamp": 1545084650987,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "0g8MTGFwdG9wUrgehes/j0A=",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 16,
"timestamp": 1545084650988,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "1A8UU21hcnRwaG9uZVK4HoXrv4JA",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 17,
"timestamp": 1545084650989,
"timestampType": "CREATE_TIME",
"key": null,
"value": "1g8USGVhZHBob25lc0jhehSuv2JA",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
}
]
}
}
51 changes: 51 additions & 0 deletions examples/powertools-examples-kafka/events/kafka-json-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"eventSource": "aws:kafka",
"eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4",
"bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
"records": {
"mytopic-0": [
{
"topic": "mytopic",
"partition": 0,
"offset": 15,
"timestamp": 1545084650987,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "eyJwcmljZSI6OTk5Ljk5LCJuYW1lIjoiTGFwdG9wIiwiaWQiOjEwMDF9",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 15,
"timestamp": 1545084650987,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "eyJwcmljZSI6NTk5Ljk5LCJuYW1lIjoiU21hcnRwaG9uZSIsImlkIjoxMDAyfQ==",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 15,
"timestamp": 1545084650987,
"timestampType": "CREATE_TIME",
"key": null,
"value": "eyJwcmljZSI6MTQ5Ljk5LCJuYW1lIjoiSGVhZHBob25lcyIsImlkIjoxMDAzfQ==",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"eventSource": "aws:kafka",
"eventSourceArn": "arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4",
"bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
"records": {
"mytopic-0": [
{
"topic": "mytopic",
"partition": 0,
"offset": 15,
"timestamp": 1545084650987,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "COkHEgZMYXB0b3AZUrgehes/j0A=",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 16,
"timestamp": 1545084650988,
"timestampType": "CREATE_TIME",
"key": "NDI=",
"value": "COoHEgpTbWFydHBob25lGVK4HoXrv4JA",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
},
{
"topic": "mytopic",
"partition": 0,
"offset": 17,
"timestamp": 1545084650989,
"timestampType": "CREATE_TIME",
"key": null,
"value": "COsHEgpIZWFkcGhvbmVzGUjhehSuv2JA",
"headers": [
{
"headerKey": [104, 101, 97, 100, 101, 114, 86, 97, 108, 117, 101]
}
]
}
]
}
}
Loading
Loading