PluginExample.java
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.examples.general;
import software.amazon.lambda.durable.DurableConfig;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;
import software.amazon.lambda.durable.examples.types.GreetingRequest;
import software.amazon.lambda.durable.plugin.*;
/**
* Example demonstrating plugin instrumentation with the Durable Execution SDK.
*
* <p>This handler registers a simple logging plugin that prints lifecycle events to stdout (which appears in CloudWatch
* Logs when deployed). Deploy this and check CloudWatch to verify all hooks fire at the right times.
*
* <p>Expected output for a successful run:
*
* <pre>
* [PLUGIN] onInvocationStart: requestId=..., durableExecutionArn=..., firstInvocation=true
* [PLUGIN] onOperationStart: name=create-greeting, type=STEP
* [PLUGIN] onUserFunctionStart: name=create-greeting, attempt=1
* [PLUGIN] onUserFunctionEnd: name=create-greeting, succeeded=true
* [PLUGIN] onOperationEnd: name=create-greeting
* [PLUGIN] onOperationStart: name=transform, type=STEP
* [PLUGIN] onUserFunctionStart: name=transform, attempt=1
* [PLUGIN] onUserFunctionEnd: name=transform, succeeded=true
* [PLUGIN] onOperationEnd: name=transform
* [PLUGIN] onInvocationEnd: status=SUCCEEDED
* </pre>
*/
public class PluginExample extends DurableHandler<GreetingRequest, String> {
@Override
protected DurableConfig createConfiguration() {
return DurableConfig.builder().withPlugins(new LoggingPlugin()).build();
}
@Override
public String handleRequest(GreetingRequest input, DurableContext context) {
context.getLogger().info("Starting plugin example for {}", input.getName());
var greeting = context.step("create-greeting", String.class, stepCtx -> "Hello, " + input.getName());
var result = context.step("transform", String.class, stepCtx -> greeting.toUpperCase() + "!");
context.getLogger().info("Plugin example complete: {}", result);
return result;
}
/** A simple plugin that logs all lifecycle events to stdout. In Lambda, stdout goes to CloudWatch Logs. */
static class LoggingPlugin implements DurableExecutionPlugin {
@Override
public void onInvocationStart(InvocationInfo info) {
System.out.printf(
"[PLUGIN] onInvocationStart: requestId=%s, durableExecutionArn=%s, firstInvocation=%s%n",
info.requestId(), info.durableExecutionArn(), info.isFirstInvocation());
}
@Override
public void onInvocationEnd(InvocationEndInfo info) {
System.out.printf(
"[PLUGIN] onInvocationEnd: status=%s, error=%s%n",
info.invocationStatus(),
info.executionError() != null ? info.executionError().getMessage() : null);
}
@Override
public void onOperationStart(OperationInfo info) {
System.out.printf(
"[PLUGIN] onOperationStart: name=%s, type=%s, id=%s%n", info.name(), info.type(), info.id());
}
@Override
public void onOperationEnd(OperationEndInfo info) {
System.out.printf(
"[PLUGIN] onOperationEnd: name=%s, type=%s, error=%s%n",
info.name(),
info.type(),
info.error() != null ? info.error().getMessage() : null);
}
@Override
public void onUserFunctionStart(UserFunctionStartInfo info) {
System.out.printf(
"[PLUGIN] onUserFunctionStart: name=%s, type=%s, attempt=%s, isReplayingChildren=%s%n",
info.name(), info.type(), info.attempt(), info.isReplayingChildren());
}
@Override
public void onUserFunctionEnd(UserFunctionEndInfo info) {
System.out.printf(
"[PLUGIN] onUserFunctionEnd: name=%s, succeeded=%s, error=%s%n",
info.name(),
info.succeeded(),
info.error() != null ? info.error().getMessage() : null);
}
}
}