diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml
new file mode 100644
index 00000000..91b870bf
--- /dev/null
+++ b/.github/workflows/samples.yml
@@ -0,0 +1,30 @@
+# This workflow will be triggered if there will be changes to aws-lambda-java-core
+# package and it builds the package and the packages that depend on it.
+
+name: Java CI samples
+
+on:
+ push:
+ branches: [ master ]
+ paths:
+ - 'samples/kinesis-firehose-event-handler/**'
+ pull_request:
+ branches: [ '*' ]
+ paths:
+ - 'samples/kinesis-firehose-event-handler/**'
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+
+ # Install base module
+ - name: Install Kinesis Firehose Sample with Maven
+ run: mvn -B install --file samples/kinesis-firehose-event-handler/pom.xml
diff --git a/samples/kinesis-firehose-event-handler/pom.xml b/samples/kinesis-firehose-event-handler/pom.xml
new file mode 100644
index 00000000..e291ef3c
--- /dev/null
+++ b/samples/kinesis-firehose-event-handler/pom.xml
@@ -0,0 +1,75 @@
+
+ 4.0.0
+
+ com.amazonaws
+ aws-lambda-java-events-examples
+ 1.0.0
+ jar
+
+ AWS Lambda Java Events Samples - KinesisFirehose
+
+ AWS Lambda Java Function Examples
+
+ https://aws.amazon.com/lambda/
+
+
+ Apache License, Version 2.0
+ https://aws.amazon.com/apache2.0
+ repo
+
+
+
+ https://github.com/aws/aws-lambda-java-libs.git
+
+
+
+ AWS Lambda team
+ Amazon Web Services
+ https://aws.amazon.com/
+
+
+
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.1
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.10.0
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
+
+ com.amazonaws
+ aws-lambda-java-tests
+ 1.1.0
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+
+
diff --git a/samples/kinesis-firehose-event-handler/src/main/java/example/KinesisFirehoseEventHandler.java b/samples/kinesis-firehose-event-handler/src/main/java/example/KinesisFirehoseEventHandler.java
new file mode 100644
index 00000000..1d343a1f
--- /dev/null
+++ b/samples/kinesis-firehose-event-handler/src/main/java/example/KinesisFirehoseEventHandler.java
@@ -0,0 +1,36 @@
+package example;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.KinesisAnalyticsInputPreprocessingResponse;
+import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.amazonaws.services.lambda.runtime.events.KinesisAnalyticsInputPreprocessingResponse.Result.Ok;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * A sample KinesisFirehoseEvent handler
+ *
+ * For more information see the developer guide - https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html
+ */
+public class KinesisFirehoseEventHandler implements RequestHandler {
+
+ @Override
+ public KinesisAnalyticsInputPreprocessingResponse handleRequest(KinesisFirehoseEvent kinesisFirehoseEvent, Context context) {
+ List records = new ArrayList<>();
+
+ for (KinesisFirehoseEvent.Record record : kinesisFirehoseEvent.getRecords()) {
+ String recordData = new String(record.getData().array());
+ // Your business logic
+ String reversedString = new StringBuilder(recordData).reverse().toString();
+
+ records.add(new KinesisAnalyticsInputPreprocessingResponse.Record(record.getRecordId(), Ok, ByteBuffer.wrap(reversedString.getBytes(UTF_8))));
+ }
+
+ return new KinesisAnalyticsInputPreprocessingResponse(records);
+ }
+}
diff --git a/samples/kinesis-firehose-event-handler/src/test/java/example/KinesisFirehoseEventHandlerTest.java b/samples/kinesis-firehose-event-handler/src/test/java/example/KinesisFirehoseEventHandlerTest.java
new file mode 100644
index 00000000..78edbcb9
--- /dev/null
+++ b/samples/kinesis-firehose-event-handler/src/test/java/example/KinesisFirehoseEventHandlerTest.java
@@ -0,0 +1,27 @@
+package example;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.KinesisAnalyticsInputPreprocessingResponse;
+import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent;
+import com.amazonaws.services.lambda.runtime.tests.annotations.Event;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public class KinesisFirehoseEventHandlerTest {
+
+ private Context context; // intentionally null as it's not used in the test
+
+ @ParameterizedTest
+ @Event(value = "event.json", type = KinesisFirehoseEvent.class)
+ public void testEventHandler(KinesisFirehoseEvent event) {
+ KinesisFirehoseEventHandler kinesisFirehoseEventHandler = new KinesisFirehoseEventHandler();
+ KinesisAnalyticsInputPreprocessingResponse response = kinesisFirehoseEventHandler.handleRequest(event, context);
+
+ String expectedString = "\n!dlroW olleH";
+ KinesisAnalyticsInputPreprocessingResponse.Record firstRecord = response.getRecords().get(0);
+ Assertions.assertEquals(expectedString, UTF_8.decode(firstRecord.getData()).toString());
+ Assertions.assertEquals(KinesisAnalyticsInputPreprocessingResponse.Result.Ok, firstRecord.getResult());
+ }
+}
\ No newline at end of file
diff --git a/samples/kinesis-firehose-event-handler/src/test/resources/event.json b/samples/kinesis-firehose-event-handler/src/test/resources/event.json
new file mode 100644
index 00000000..08dd9025
--- /dev/null
+++ b/samples/kinesis-firehose-event-handler/src/test/resources/event.json
@@ -0,0 +1,19 @@
+{
+ "invocationId": "invoked123",
+ "deliveryStreamArn": "aws:lambda:events",
+ "region": "us-west-2",
+ "records": [
+ {
+ "data": "SGVsbG8gV29ybGQhCg==",
+ "recordId": "record2",
+ "approximateArrivalTimestamp": 1510772160000,
+ "kinesisRecordMetadata": {
+ "shardId": "shardId-000000000000",
+ "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a",
+ "approximateArrivalTimestamp": "2012-04-23T18:25:43.511Z",
+ "sequenceNumber": "49546986683135544286507457936321625675700192471156785154",
+ "subsequenceNumber": ""
+ }
+ }
+ ]
+}
\ No newline at end of file