Package software.amazon.awscdk.services.pipes.alpha
Amazon EventBridge Pipes Construct Library
---
The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the Semantic Versioning model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
EventBridge Pipes let you create source to target connections between several aws services. While transporting messages from a source to a target the messages can be filtered, transformed and enriched.
For more details see the service documentation:
Pipe
EventBridge Pipes is a fully managed service that enables point-to-point integrations between event producers and consumers. Pipes can be used to connect several AWS services to each other, or to connect AWS services to external services.
A Pipe has a source and a target. The source events can be filtered and enriched before reaching the target.
Example - pipe usage
The following code examples use an example implementation of a source and target. In the future there will be separate packages for the sources and targets.
To define a pipe you need to create a new Pipe
construct. The Pipe
construct needs a source and a target.
Queue sourceQueue; Queue targetQueue; Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue)) .build();
This minimal example creates a pipe with a SQS queue as source and a SQS queue as target. Messages from the source are put into the body of the target message.
Source
A source is a AWS Service that is polled. The following Sources are possible:
- Amazon DynamoDB stream
- Amazon Kinesis stream
- Amazon MQ broker
- Amazon MSK stream
- Self managed Apache Kafka stream
- Amazon SQS queue
Currently no implementation exist for any of the supported sources. The following example shows how an implementation can look like. The actual implementation is not part of this package and will be in a separate one.
Example source implementation
public class SqsSource implements ISource { public String sourceArn; public Object sourceParameters; public SqsSource(Queue queue) { this.queue = queue; this.sourceArn = queue.getQueueArn(); } public SourceConfig bind(IPipe _pipe) { return SourceConfig.builder() .sourceParameters(this.sourceParameters) .build(); } public void grantRead(IRole pipeRole) { this.queue.grantConsumeMessages(pipeRole); } }
A source implementation needs to provide the sourceArn
, sourceParameters
and grant the pipe role read access to the source.
Filter
A Filter can be used to filter the events from the source before they are forwarded to the enrichment or, if no enrichment is present, target step. Multiple filter expressions are possible. If one of the filter expressions matches the event is forwarded to the enrichment or target step.
Example - filter usage
Queue sourceQueue; Queue targetQueue; Filter sourceFilter = new Filter(List.of(FilterPattern.fromObject(Map.of( "body", Map.of( // only forward events with customerType B2B or B2C "customerType", List.of("B2B", "B2C")))))); Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue)) .filter(sourceFilter) .build();
This example shows a filter that only forwards events with the customerType
B2B or B2C from the source messages. Messages that are not matching the filter are not forwarded to the enrichment or target step.
You can define multiple filter pattern which are combined with a logical OR
.
Additional filter pattern and details can be found in the EventBridge pipes docs
Input transformation
For enrichments and targets the input event can be transformed. The transformation is applied for each item of the batch. A transformation has access to the input event as well to some context information of the pipe itself like the name of the pipe. See docs for details.
Example - input transformation from object
The input transformation can be created from an object. The object can contain static values, dynamic values or pipe variables.
Queue sourceQueue; Queue targetQueue; InputTransformation targetInputTransformation = InputTransformation.fromObject(Map.of( "staticField", "static value", "dynamicField", DynamicInput.fromEventPath("$.body.payload"), "pipeVariable", DynamicInput.getPipeName())); Pipe pipe = Pipe.Builder.create(this, "Pipe") .pipeName("MyPipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue, Map.of( "inputTransformation", targetInputTransformation))) .build();
This example shows a transformation that adds a static field, a dynamic field and a pipe variable to the input event. The dynamic field is extracted from the input event. The pipe variable is extracted from the pipe context.
So when the following batch of input events is processed by the pipe
[ { ... "body": "{\"payload\": \"Test message.\"}", ... } ]
it is converted into the following payload.
[ { ... "staticField": "static value", "dynamicField": "Test message.", "pipeVariable": "MyPipe", ... } ]
If the transformation is applied to a target it might be converted to a string representation. E.g. the resulting SQS message body looks like this.
[ { ... "body": "{\"staticField\": \"static value\", \"dynamicField\": \"Test message.\", \"pipeVariable\": \"MyPipe\"}", ... } ]
Example - input transformation from event path
In cases where you want to forward only a part of the event to the target you can use the transformation event path.
This only works for targets because the enrichment needs to have a valid json as input.
Queue sourceQueue; Queue targetQueue; InputTransformation targetInputTransformation = InputTransformation.fromEventPath("$.body.payload"); Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue, Map.of( "inputTransformation", targetInputTransformation))) .build();
This transformation extracts the body of the event.
So when the following batch of input events is processed by the pipe
[ { ... "body": "\"{\"payload\": \"Test message.\"}\"", ... } ]
it is converted into the following target payload.
[ { ... "body": "Test message." ... } ]
The implicit payload parsing (e.g. SQS message body to JSON) only works if the input is the source payload. Implicit body parsing is not applied on enrichment results.
Example - input transformation from text
In cases where you want to forward a static text to the target or use your own formatted inputTemplate
you can use the transformation from text.
Queue sourceQueue; Queue targetQueue; InputTransformation targetInputTransformation = InputTransformation.fromText("My static text"); Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue, Map.of( "inputTransformation", targetInputTransformation))) .build();
This transformation forwards the static text to the target.
[ { ... "body": "My static text" ... } ]
Enrichment
In the enrichment step the (un)filtered payloads from the source can be used to invoke one of the following services
- API destination
- Amazon API Gateway
- Lambda function
- Step Functions state machine
- only express workflow
Example enrichment implementation
Currently no implementation exist for any of the supported enrichments. The following example shows how an implementation can look like. The actual implementation is not part of this package and will be in a separate one.
public class LambdaEnrichment implements IEnrichment { public String enrichmentArn; private InputTransformation inputTransformation; public LambdaEnrichment(Function lambda) { this(lambda, Map.of()); } public LambdaEnrichment(Function lambda, Map<String, Object> props) { this.enrichmentArn = functionArn; this.inputTransformation = props.getInputTransformation(); } public EnrichmentParametersConfig bind(IPipe pipe) { return EnrichmentParametersConfig.builder() .enrichmentParameters(PipeEnrichmentParametersProperty.builder() .inputTemplate(this.inputTransformation.bind(pipe).getInputTemplate()) .build()) .build(); } public void grantInvoke(IRole pipeRole) { this.lambda.grantInvoke(pipeRole); } }
An enrichment implementation needs to provide the enrichmentArn
, enrichmentParameters
and grant the pipe role invoke access to the enrichment.
Example - enrichment usage
Queue sourceQueue; Queue targetQueue; Function enrichmentLambda; InputTransformation enrichmentInputTransformation = InputTransformation.fromObject(Map.of( "staticField", "static value", "dynamicField", DynamicInput.fromEventPath("$.body.payload"), "pipeVariable", DynamicInput.getPipeName())); Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue)) .enrichment(new LambdaEnrichment(enrichmentLambda, Map.of( "inputTransformation", enrichmentInputTransformation))) .build();
This example adds a lambda function as enrichment to the pipe. The lambda function is invoked with the batch of messages from the source after applying the transformation. The lambda function can return a result which is forwarded to the target.
So the following batch of input events is processed by the pipe
[ { ... "body": "{\"payload\": \"Test message.\"}", ... } ]
it is converted into the following payload which is sent to the lambda function.
[ { ... "staticField": "static value", "dynamicField": "Test message.", "pipeVariable": "MyPipe", ... } ]
The lambda function can return a result which is forwarded to the target. For example a lambda function that returns a concatenation of the static field, dynamic field and pipe variable
public Promise handler(Object event) { return event.getStaticField() + "-" + event.getDynamicField() + "-" + event.getPipeVariable(); }
will produce the following target message in the target SQS queue.
[ { ... "body": "static value-Test message.-MyPipe", ... } ]
Target
A Target is the end of the Pipe. After the payload from the source is pulled, filtered and enriched it is forwarded to the target. For now the following targets are supported:
- API destination
- API Gateway
- Batch job queue
- CloudWatch log group
- ECS task
- Event bus in the same account and Region
- Firehose delivery stream
- Inspector assessment template
- Kinesis stream
- Lambda function (SYNC or ASYNC)
- Redshift cluster data API queries
- SageMaker Pipeline
- SNS topic
- SQS queue
- Step Functions state machine
- Express workflows (ASYNC)
- Standard workflows (SYNC or ASYNC)
The target event can be transformed before it is forwarded to the target using the same input transformation as in the enrichment step.
Example target implementation
Currently no implementation exist for any of the supported targets. The following example shows how an implementation can look like. The actual implementation is not part of this package and will be in a separate one.
public class SqsTarget implements ITarget { public String targetArn; private InputTransformation inputTransformation; public SqsTarget(Queue queue) { this(queue, Map.of()); } public SqsTarget(Queue queue, Map<String, Object> props) { this.queue = queue; this.targetArn = queue.getQueueArn(); this.inputTransformation = props.getInputTransformation(); } public TargetConfig bind(Pipe _pipe) { return TargetConfig.builder() .targetParameters(PipeTargetParametersProperty.builder() .inputTemplate(this.inputTransformation.bind(_pipe).getInputTemplate()) .build()) .build(); } public void grantPush(IRole pipeRole) { this.queue.grantSendMessages(pipeRole); } }
A target implementation needs to provide the targetArn
, enrichmentParameters
and grant the pipe role invoke access to the enrichment.
Log destination
A pipe can produce log events that are forwarded to different log destinations. You can configure multiple destinations, but all the destination share the same log level and log data. For details check the official documentation.
The log level and data that is included in the log events is configured on the pipe class itself. Whereas the actual destination is defined independent.
Example log destination implementation
Currently no implementation exist for any of the supported enrichments. The following example shows how an implementation can look like. The actual implementation is not part of this package and will be in a separate one.
public class CloudwatchDestination implements ILogDestination { public LogDestinationParameters parameters; public CloudwatchDestination(LogGroup logGroup) { this.logGroup = logGroup; this.parameters = LogDestinationParameters.builder() .cloudwatchLogsLogDestination(CloudwatchLogsLogDestinationProperty.builder() .logGroupArn(logGroup.getLogGroupArn()) .build()) .build(); } public LogDestinationConfig bind(IPipe _pipe) { return LogDestinationConfig.builder() .parameters(this.parameters) .build(); } public void grantPush(IRole pipeRole) { this.logGroup.grantWrite(pipeRole); } }
Example log destination usage
Queue sourceQueue; Queue targetQueue; LogGroup loggroup; Pipe pipe = Pipe.Builder.create(this, "Pipe") .source(new SqsSource(sourceQueue)) .target(new SqsTarget(targetQueue)) .logLevel(LogLevel.TRACE) .logIncludeExecutionData(List.of(IncludeExecutionData.ALL)) .logDestinations(List.of( new CloudwatchDestination(loggroup))) .build();
This example uses a cloudwatch loggroup to store the log emitted during a pipe execution. The log level is set to TRACE
so all steps of the pipe are logged.
Additionally all execution data is logged as well.
-
ClassDescription(experimental) The state the pipe should be in.(experimental) Dynamic variables that can be used in the input transformation.(experimental) The parameters required to set up enrichment on your pipe.A builder for
EnrichmentParametersConfig
An implementation forEnrichmentParametersConfig
(experimental) The collection of event patterns used to filter events.(experimental) Generate a filter pattern from an input.(experimental) Enrichment step to enhance the data from the source before sending it to the target.Internal default implementation forIEnrichment
.A proxy class which represents a concrete javascript instance of this type.(experimental) The collection of event patterns used to filter events.Internal default implementation forIFilter
.A proxy class which represents a concrete javascript instance of this type.(experimental) Filter events using an event pattern.Internal default implementation forIFilterPattern
.A proxy class which represents a concrete javascript instance of this type.(experimental) Transform or replace the input event payload.Internal default implementation forIInputTransformation
.A proxy class which represents a concrete javascript instance of this type.(experimental) Log destination base class.Internal default implementation forILogDestination
.A proxy class which represents a concrete javascript instance of this type.(experimental) Log data configuration for a pipe.(experimental) Transform or replace the input event payload.(experimental) The inputTemplate that is used to transform the input event payload with unquoted variables.A builder forInputTransformationConfig
An implementation forInputTransformationConfig
(experimental) Interface representing a created or an importedPipe
.Internal default implementation forIPipe
.A proxy class which represents a concrete javascript instance of this type.(experimental) Source interface.Internal default implementation forISource
.A proxy class which represents a concrete javascript instance of this type.(experimental) Target configuration.Internal default implementation forITarget
.A proxy class which represents a concrete javascript instance of this type.(experimental) Log destination configuration.A builder forLogDestinationConfig
An implementation forLogDestinationConfig
(experimental) Log destination configuration parameters.A builder forLogDestinationParameters
An implementation forLogDestinationParameters
(experimental) Log configuration for a pipe.(experimental) Amazon EventBridge Pipes connects sources to targets.(experimental) A fluent builder forPipe
.(experimental) Properties for a pipe.A builder forPipeProps
An implementation forPipeProps
(experimental) Reserved pipe variables.(experimental) Source properties.A builder forSourceConfig
An implementation forSourceConfig
(experimental) Source properties.A builder forSourceParameters
An implementation forSourceParameters
(experimental) Sources that support a dead-letter target.(experimental) Target config properties.A builder forTargetConfig
An implementation forTargetConfig
(experimental) Define dynamic target parameters.