Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:28:34 +08:00
commit 390afca02b
220 changed files with 86013 additions and 0 deletions

View File

@@ -0,0 +1,508 @@
---
name: aws-sdk-java-v2-lambda
description: AWS Lambda patterns using AWS SDK for Java 2.x. Use when invoking Lambda functions, creating/updating functions, managing function configurations, working with Lambda layers, or integrating Lambda with Spring Boot applications.
category: aws
tags: [aws, lambda, java, sdk, serverless, functions]
version: 1.1.0
allowed-tools: Read, Write, Bash
---
# AWS SDK for Java 2.x - AWS Lambda
## When to Use
Use this skill when:
- Invoking Lambda functions programmatically
- Creating or updating Lambda functions
- Managing Lambda function configurations
- Working with Lambda environment variables
- Managing Lambda layers and aliases
- Implementing asynchronous Lambda invocations
- Integrating Lambda with Spring Boot
## Overview
AWS Lambda is a compute service that runs code without the need to manage servers. Your code runs automatically, scaling up and down with pay-per-use pricing. Use this skill to implement AWS Lambda operations using AWS SDK for Java 2.x in applications and services.
## Dependencies
```xml
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>lambda</artifactId>
</dependency>
```
## Client Setup
To use AWS Lambda, create a LambdaClient with the required region configuration:
```java
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.LambdaClient;
LambdaClient lambdaClient = LambdaClient.builder()
.region(Region.US_EAST_1)
.build();
```
For asynchronous operations, use LambdaAsyncClient:
```java
import software.amazon.awssdk.services.lambda.LambdaAsyncClient;
LambdaAsyncClient asyncLambdaClient = LambdaAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
```
## Invoke Lambda Function
### Synchronous Invocation
Invoke Lambda functions synchronously to get immediate results:
```java
import software.amazon.awssdk.services.lambda.model.*;
import software.amazon.awssdk.core.SdkBytes;
public String invokeLambda(LambdaClient lambdaClient,
String functionName,
String payload) {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(payload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
return response.payload().asUtf8String();
}
```
### Asynchronous Invocation
Use asynchronous invocation for fire-and-forget scenarios:
```java
public void invokeLambdaAsync(LambdaClient lambdaClient,
String functionName,
String payload) {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.invocationType(InvocationType.EVENT) // Asynchronous
.payload(SdkBytes.fromUtf8String(payload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
System.out.println("Status: " + response.statusCode());
}
```
### Invoke with JSON Objects
Work with JSON payloads for complex data structures:
```java
import com.fasterxml.jackson.databind.ObjectMapper;
public <T> String invokeLambdaWithObject(LambdaClient lambdaClient,
String functionName,
T requestObject) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonPayload = mapper.writeValueAsString(requestObject);
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
return response.payload().asUtf8String();
}
```
### Parse Typed Responses
Parse JSON responses into typed objects:
```java
public <T> T invokeLambdaAndParse(LambdaClient lambdaClient,
String functionName,
Object request,
Class<T> responseType) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonPayload = mapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(invokeRequest);
String responseJson = response.payload().asUtf8String();
return mapper.readValue(responseJson, responseType);
}
```
## Function Management
### List Functions
List all Lambda functions for the current account:
```java
public List<FunctionConfiguration> listFunctions(LambdaClient lambdaClient) {
ListFunctionsResponse response = lambdaClient.listFunctions();
return response.functions();
}
```
### Get Function Configuration
Retrieve function configuration and metadata:
```java
public FunctionConfiguration getFunctionConfig(LambdaClient lambdaClient,
String functionName) {
GetFunctionRequest request = GetFunctionRequest.builder()
.functionName(functionName)
.build();
GetFunctionResponse response = lambdaClient.getFunction(request);
return response.configuration();
}
```
### Update Function Code
Update Lambda function code with new deployment package:
```java
import java.nio.file.Files;
import java.nio.file.Paths;
public void updateFunctionCode(LambdaClient lambdaClient,
String functionName,
String zipFilePath) throws IOException {
byte[] zipBytes = Files.readAllBytes(Paths.get(zipFilePath));
UpdateFunctionCodeRequest request = UpdateFunctionCodeRequest.builder()
.functionName(functionName)
.zipFile(SdkBytes.fromByteArray(zipBytes))
.publish(true)
.build();
UpdateFunctionCodeResponse response = lambdaClient.updateFunctionCode(request);
System.out.println("Updated function version: " + response.version());
}
```
### Update Function Configuration
Modify function settings like timeout, memory, and environment variables:
```java
public void updateFunctionConfiguration(LambdaClient lambdaClient,
String functionName,
Map<String, String> environment) {
Environment env = Environment.builder()
.variables(environment)
.build();
UpdateFunctionConfigurationRequest request = UpdateFunctionConfigurationRequest.builder()
.functionName(functionName)
.environment(env)
.timeout(60)
.memorySize(512)
.build();
lambdaClient.updateFunctionConfiguration(request);
}
```
### Create Function
Create new Lambda functions with code and configuration:
```java
public void createFunction(LambdaClient lambdaClient,
String functionName,
String roleArn,
String handler,
String zipFilePath) throws IOException {
byte[] zipBytes = Files.readAllBytes(Paths.get(zipFilePath));
FunctionCode code = FunctionCode.builder()
.zipFile(SdkBytes.fromByteArray(zipBytes))
.build();
CreateFunctionRequest request = CreateFunctionRequest.builder()
.functionName(functionName)
.runtime(Runtime.JAVA17)
.role(roleArn)
.handler(handler)
.code(code)
.timeout(60)
.memorySize(512)
.build();
CreateFunctionResponse response = lambdaClient.createFunction(request);
System.out.println("Function ARN: " + response.functionArn());
}
```
### Delete Function
Remove Lambda functions when no longer needed:
```java
public void deleteFunction(LambdaClient lambdaClient, String functionName) {
DeleteFunctionRequest request = DeleteFunctionRequest.builder()
.functionName(functionName)
.build();
lambdaClient.deleteFunction(request);
}
```
## Spring Boot Integration
### Configuration
Configure Lambda clients as Spring beans:
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LambdaConfiguration {
@Bean
public LambdaClient lambdaClient() {
return LambdaClient.builder()
.region(Region.US_EAST_1)
.build();
}
}
```
### Lambda Invoker Service
Create a service for Lambda function invocation:
```java
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class LambdaInvokerService {
private final LambdaClient lambdaClient;
private final ObjectMapper objectMapper;
@Autowired
public LambdaInvokerService(LambdaClient lambdaClient, ObjectMapper objectMapper) {
this.lambdaClient = lambdaClient;
this.objectMapper = objectMapper;
}
public <T, R> R invoke(String functionName, T request, Class<R> responseType) {
try {
String jsonPayload = objectMapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(invokeRequest);
if (response.functionError() != null) {
throw new LambdaInvocationException(
"Lambda function error: " + response.functionError());
}
String responseJson = response.payload().asUtf8String();
return objectMapper.readValue(responseJson, responseType);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Lambda function", e);
}
}
public void invokeAsync(String functionName, Object request) {
try {
String jsonPayload = objectMapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.invocationType(InvocationType.EVENT)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
lambdaClient.invoke(invokeRequest);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Lambda function async", e);
}
}
}
```
### Typed Lambda Client
Create type-safe interfaces for Lambda services:
```java
public interface OrderProcessor {
OrderResponse processOrder(OrderRequest request);
}
@Service
public class LambdaOrderProcessor implements OrderProcessor {
private final LambdaInvokerService lambdaInvoker;
@Value("${lambda.order-processor.function-name}")
private String functionName;
public LambdaOrderProcessor(LambdaInvokerService lambdaInvoker) {
this.lambdaInvoker = lambdaInvoker;
}
@Override
public OrderResponse processOrder(OrderRequest request) {
return lambdaInvoker.invoke(functionName, request, OrderResponse.class);
}
}
```
## Error Handling
Implement comprehensive error handling for Lambda operations:
```java
public String invokeLambdaSafe(LambdaClient lambdaClient,
String functionName,
String payload) {
try {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(payload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
// Check for function error
if (response.functionError() != null) {
String errorMessage = response.payload().asUtf8String();
throw new RuntimeException("Lambda error: " + errorMessage);
}
// Check status code
if (response.statusCode() != 200) {
throw new RuntimeException("Lambda invocation failed with status: " +
response.statusCode());
}
return response.payload().asUtf8String();
} catch (LambdaException e) {
System.err.println("Lambda error: " + e.awsErrorDetails().errorMessage());
throw e;
}
}
public class LambdaInvocationException extends RuntimeException {
public LambdaInvocationException(String message) {
super(message);
}
public LambdaInvocationException(String message, Throwable cause) {
super(message, cause);
}
}
```
## Examples
For comprehensive code examples, see the references section:
- **Basic examples** - Simple invocation patterns and function management
- **Spring Boot integration** - Complete Spring Boot configuration and service patterns
- **Testing examples** - Unit and integration test patterns
- **Advanced patterns** - Complex scenarios and best practices
## Best Practices
1. **Reuse Lambda clients**: Create once and reuse across invocations
2. **Set appropriate timeouts**: Match client timeout to Lambda function timeout
3. **Use async invocation**: For fire-and-forget scenarios
4. **Handle errors properly**: Check for function errors and status codes
5. **Use environment variables**: For function configuration
6. **Implement retry logic**: For transient failures
7. **Monitor invocations**: Use CloudWatch metrics
8. **Version functions**: Use aliases and versions for production
9. **Use VPC**: For accessing resources in private subnets
10. **Optimize payload size**: Keep payloads small for better performance
## Testing
Test Lambda services using mocks and test assertions:
```java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class LambdaInvokerServiceTest {
@Mock
private LambdaClient lambdaClient;
@Mock
private ObjectMapper objectMapper;
@InjectMocks
private LambdaInvokerService service;
@Test
void shouldInvokeLambdaSuccessfully() throws Exception {
// Test implementation
}
}
```
## Related Skills
- @aws-sdk-java-v2-core - Core AWS SDK patterns and client configuration
- @spring-boot-dependency-injection - Spring dependency injection best practices
- @unit-test-service-layer - Service testing patterns with Mockito
- @spring-boot-actuator - Production monitoring and health checks
## References
For detailed information and examples, see the following reference files:
- **[Official Documentation](references/official-documentation.md)** - AWS Lambda concepts, API reference, and official guidance
- **[Examples](references/examples.md)** - Complete code examples and integration patterns
## Additional Resources
- [Lambda Examples on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/lambda)
- [Lambda API Reference](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/package-summary.html)
- [AWS Lambda Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)

View File

@@ -0,0 +1,544 @@
# AWS Lambda Java SDK Examples
## Client Setup
### Basic Client Configuration
```java
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.LambdaClient;
// Create synchronous client
LambdaClient lambdaClient = LambdaClient.builder()
.region(Region.US_EAST_1)
.build();
// Create asynchronous client
LambdaAsyncClient asyncLambdaClient = LambdaAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
```
### Client with Configuration
```java
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.http.nio.netty.NettyNioHttpServer;
LambdaClient lambdaClient = LambdaClient.builder()
.region(Region.US_EAST_1)
.credentialsProvider(DefaultCredentialsProvider.create())
.httpClientBuilder(NettyNioHttpServer.builder())
.build();
```
## Function Invocation Examples
### Synchronous Invocation with String Payload
```java
import software.amazon.awssdk.services.lambda.model.*;
import software.amazon.awssdk.core.SdkBytes;
public String invokeLambdaSync(LambdaClient lambdaClient,
String functionName,
String payload) {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(payload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
// Check for function errors
if (response.functionError() != null) {
throw new RuntimeException("Lambda function error: " +
response.payload().asUtf8String());
}
return response.payload().asUtf8String();
}
```
### Asynchronous Invocation
```java
import java.util.concurrent.CompletableFuture;
public CompletableFuture<String> invokeLambdaAsync(LambdaClient lambdaClient,
String functionName,
String payload) {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.invocationType(InvocationType.EVENT) // Asynchronous
.payload(SdkBytes.fromUtf8String(payload))
.build();
return lambdaClient.invoke(request)
.thenApply(response -> response.payload().asUtf8String());
}
```
### Invocation with JSON Object
```java
import com.fasterxml.jackson.databind.ObjectMapper;
public <T> String invokeLambdaWithObject(LambdaClient lambdaClient,
String functionName,
T requestObject) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonPayload = mapper.writeValueAsString(requestObject);
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
return response.payload().asUtf8String();
}
```
### Parse Typed Response
```java
import com.fasterxml.jackson.databind.ObjectMapper;
public <T> T invokeLambdaAndParse(LambdaClient lambdaClient,
String functionName,
Object request,
Class<T> responseType) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonPayload = mapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(invokeRequest);
String responseJson = response.payload().asUtf8String();
return mapper.readValue(responseJson, responseType);
}
```
## Function Management Examples
### List Functions
```java
public List<FunctionConfiguration> listLambdaFunctions(LambdaClient lambdaClient) {
ListFunctionsResponse response = lambdaClient.listFunctions();
return response.functions();
}
// List functions with pagination
public List<FunctionConfiguration> listAllFunctions(LambdaClient lambdaClient) {
ListFunctionsRequest request = ListFunctionsRequest.builder().build();
ListFunctionsResponse response = lambdaClient.listFunctions(request);
return response.functions();
}
```
### Get Function Configuration
```java
public FunctionConfiguration getFunctionConfig(LambdaClient lambdaClient,
String functionName) {
GetFunctionRequest request = GetFunctionRequest.builder()
.functionName(functionName)
.build();
GetFunctionResponse response = lambdaClient.getFunction(request);
return response.configuration();
}
```
### Get Function Code
```java
public byte[] getFunctionCode(LambdaClient lambdaClient,
String functionName) {
GetFunctionRequest request = GetFunctionRequest.builder()
.functionName(functionName)
.build();
GetFunctionResponse response = lambdaClient.getFunction(request);
return response.code().zipFile().asByteArray();
}
```
### Update Function Code
```java
import java.nio.file.Files;
import java.nio.file.Paths;
public void updateLambdaFunction(LambdaClient lambdaClient,
String functionName,
String zipFilePath) throws IOException {
byte[] zipBytes = Files.readAllBytes(Paths.get(zipFilePath));
UpdateFunctionCodeRequest request = UpdateFunctionCodeRequest.builder()
.functionName(functionName)
.zipFile(SdkBytes.fromByteArray(zipBytes))
.publish(true) // Create new version
.build();
UpdateFunctionCodeResponse response = lambdaClient.updateFunctionCode(request);
System.out.println("Updated function version: " + response.version());
}
```
### Update Function Configuration
```java
public void updateFunctionConfig(LambdaClient lambdaClient,
String functionName,
Map<String, String> environment) {
Environment env = Environment.builder()
.variables(environment)
.build();
UpdateFunctionConfigurationRequest request = UpdateFunctionConfigurationRequest.builder()
.functionName(functionName)
.environment(env)
.timeout(60)
.memorySize(512)
.build();
lambdaClient.updateFunctionConfiguration(request);
}
```
### Create Function
```java
import java.nio.file.Files;
import java.nio.file.Paths;
public void createLambdaFunction(LambdaClient lambdaClient,
String functionName,
String roleArn,
String handler,
String zipFilePath) throws IOException {
byte[] zipBytes = Files.readAllBytes(Paths.get(zipFilePath));
FunctionCode code = FunctionCode.builder()
.zipFile(SdkBytes.fromByteArray(zipBytes))
.build();
CreateFunctionRequest request = CreateFunctionRequest.builder()
.functionName(functionName)
.runtime(Runtime.JAVA17)
.role(roleArn)
.handler(handler)
.code(code)
.timeout(60)
.memorySize(512)
.environment(Environment.builder()
.variables(Map.of("ENV", "production"))
.build())
.build();
CreateFunctionResponse response = lambdaClient.createFunction(request);
System.out.println("Function ARN: " + response.functionArn());
}
```
### Delete Function
```java
public void deleteLambdaFunction(LambdaClient lambdaClient, String functionName) {
DeleteFunctionRequest request = DeleteFunctionRequest.builder()
.functionName(functionName)
.build();
lambdaClient.deleteFunction(request);
}
```
## Spring Boot Integration Examples
### Configuration Class
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LambdaConfiguration {
@Bean
public LambdaClient lambdaClient() {
return LambdaClient.builder()
.region(Region.US_EAST_1)
.build();
}
@Bean
public LambdaAsyncClient asyncLambdaClient() {
return LambdaAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
}
}
```
### Lambda Invoker Service
```java
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class LambdaInvokerService {
private final LambdaClient lambdaClient;
private final ObjectMapper objectMapper;
@Autowired
public LambdaInvokerService(LambdaClient lambdaClient,
ObjectMapper objectMapper) {
this.lambdaClient = lambdaClient;
this.objectMapper = objectMapper;
}
public <T, R> R invokeFunction(String functionName,
T request,
Class<R> responseType) {
try {
String jsonPayload = objectMapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
InvokeResponse response = lambdaClient.invoke(invokeRequest);
if (response.functionError() != null) {
throw new LambdaInvocationException(
"Lambda function error: " + response.functionError());
}
String responseJson = response.payload().asUtf8String();
return objectMapper.readValue(responseJson, responseType);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Lambda function", e);
}
}
public void invokeFunctionAsync(String functionName, Object request) {
try {
String jsonPayload = objectMapper.writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.invocationType(InvocationType.EVENT)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
lambdaClient.invoke(invokeRequest);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Lambda function async", e);
}
}
}
```
### Typed Lambda Client Interface
```java
public interface OrderProcessor {
OrderResponse processOrder(OrderRequest request);
CompletableFuture<OrderResponse> processOrderAsync(OrderRequest request);
}
@Service
public class LambdaOrderProcessor implements OrderProcessor {
private final LambdaInvokerService lambdaInvoker;
private final LambdaAsyncClient asyncLambdaClient;
@Value("${lambda.order-processor.function-name}")
private String functionName;
public LambdaOrderProcessor(LambdaInvokerService lambdaInvoker,
LambdaAsyncClient asyncLambdaClient) {
this.lambdaInvoker = lambdaInvoker;
this.asyncLambdaClient = asyncLambdaClient;
}
@Override
public OrderResponse processOrder(OrderRequest request) {
return lambdaInvoker.invoke(functionName, request, OrderResponse.class);
}
@Override
public CompletableFuture<OrderResponse> processOrderAsync(OrderRequest request) {
// Implement async invocation using async client
try {
String jsonPayload = new ObjectMapper().writeValueAsString(request);
InvokeRequest invokeRequest = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(jsonPayload))
.build();
return asyncLambdaClient.invoke(invokeRequest)
.thenApply(response -> {
try {
return new ObjectMapper().readValue(
response.payload().asUtf8String(),
OrderResponse.class);
} catch (Exception e) {
throw new RuntimeException("Failed to parse response", e);
}
});
} catch (Exception e) {
throw new RuntimeException("Failed to invoke Lambda function", e);
}
}
}
```
## Error Handling Examples
### Comprehensive Error Handling
```java
public String invokeLambdaWithFullErrorHandling(LambdaClient lambdaClient,
String functionName,
String payload) {
try {
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(SdkBytes.fromUtf8String(payload))
.build();
InvokeResponse response = lambdaClient.invoke(request);
// Check for function error
if (response.functionError() != null) {
String errorMessage = response.payload().asUtf8String();
throw new LambdaInvocationException(
"Lambda function error: " + errorMessage);
}
// Check status code
if (response.statusCode() != 200) {
throw new LambdaInvocationException(
"Lambda invocation failed with status: " + response.statusCode());
}
return response.payload().asUtf8String();
} catch (LambdaException e) {
System.err.println("AWS Lambda error: " + e.awsErrorDetails().errorMessage());
throw new LambdaInvocationException(
"AWS Lambda service error: " + e.awsErrorDetails().errorMessage(), e);
}
}
public class LambdaInvocationException extends RuntimeException {
public LambdaInvocationException(String message) {
super(message);
}
public LambdaInvocationException(String message, Throwable cause) {
super(message, cause);
}
}
```
## Testing Examples
### Unit Test for Lambda Service
```java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
class LambdaInvokerServiceTest {
@Mock
private LambdaClient lambdaClient;
@Mock
private ObjectMapper objectMapper;
@InjectMocks
private LambdaInvokerService service;
@Test
void shouldInvokeLambdaSuccessfully() throws Exception {
// Given
OrderRequest request = new OrderRequest("ORDER-123");
OrderResponse expectedResponse = new OrderResponse("SUCCESS");
String jsonPayload = "{\"orderId\":\"ORDER-123\"};
String jsonResponse = "{\"status\":\"SUCCESS\"};
when(objectMapper.writeValueAsString(request))
.thenReturn(jsonPayload);
when(lambdaClient.invoke(any(InvokeRequest.class)))
.thenReturn(InvokeResponse.builder()
.statusCode(200)
.payload(SdkBytes.fromUtf8String(jsonResponse))
.build());
when(objectMapper.readValue(jsonResponse, OrderResponse.class))
.thenReturn(expectedResponse);
// When
OrderResponse result = service.invoke(
"order-processor", request, OrderResponse.class);
// Then
assertThat(result).isEqualTo(expectedResponse);
verify(lambdaClient).invoke(any(InvokeRequest.class));
}
@Test
void shouldHandleFunctionError() throws Exception {
// Given
OrderRequest request = new OrderRequest("ORDER-123");
String jsonPayload = "{\"orderId\":\"ORDER-123\"};
String errorResponse = "{\"errorMessage\":\"Invalid input\"};
when(objectMapper.writeValueAsString(request))
.thenReturn(jsonPayload);
when(lambdaClient.invoke(any(InvokeRequest.class)))
.thenReturn(InvokeResponse.builder()
.statusCode(200)
.functionError("Unhandled")
.payload(SdkBytes.fromUtf8String(errorResponse))
.build());
// When & Then
assertThatThrownBy(() ->
service.invoke("order-processor", request, OrderResponse.class))
.isInstanceOf(LambdaInvocationException.class)
.hasMessageContaining("Lambda function error");
}
}
```
## Maven Dependencies
```xml
<!-- AWS SDK for Java v2 Lambda -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>lambda</artifactId>
<version>2.36.3</version> // Use the latest version available
</dependency>
<!-- Jackson for JSON processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Spring Boot support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```

View File

@@ -0,0 +1,112 @@
# AWS Lambda Official Documentation Reference
## Overview
AWS Lambda is a compute service that runs code without the need to manage servers. Your code runs automatically, scaling up and down with pay-per-use pricing.
## Common Use Cases
- Stream processing: Process real-time data streams for analytics
- Web applications: Build scalable web apps that automatically adjust
- Mobile backends: Create secure API backends
- IoT backends: Handle web, mobile, IoT, and third-party API requests
- File processing: Process files automatically when uploaded
- Database operations: Respond to database changes and automate data workflows
- Scheduled tasks: Run automated operations on a regular schedule
## How Lambda Works
1. You write and organize your code in Lambda functions
2. You control security through Lambda permissions using execution roles
3. Event sources and AWS services trigger your Lambda functions
4. Lambda runs your code with language-specific runtimes
## Key Features
### Configuration & Security
- Environment variables modify behavior without deployments
- Versions safely test new features while maintaining stable production
- Lambda layers optimize code reuse across multiple functions
- Code signing ensures only approved code reaches production
### Performance
- Concurrency controls manage responsiveness and resource utilization
- Lambda SnapStart reduces cold start times to sub-second performance
- Response streaming delivers large payloads incrementally
- Container images package functions with complex dependencies
### Integration
- VPC networks secure sensitive resources and internal services
- File system integration shares persistent data across function invocations
- Function URLs create public APIs without additional services
- Lambda extensions augment functions with monitoring and operational tools
## AWS Lambda Java SDK API
### Key Classes
- `LambdaClient` - Synchronous service client
- `LambdaAsyncClient` - Asynchronous service client
- `LambdaClientBuilder` - Builder for synchronous client
- `LambdaAsyncClientBuilder` - Builder for asynchronous client
- `LambdaServiceClientConfiguration` - Client settings configuration
### Related Packages
- `software.amazon.awssdk.services.lambda.model` - API models
- `software.amazon.awssdk.services.lambda.transform` - Request/response transformations
- `software.amazon.awssdk.services.lambda.paginators` - Pagination utilities
- `software.amazon.awssdk.services.lambda.waiters` - Waiter utilities
### Authentication
Lambda supports signature version 4 for API authentication.
### CA Requirements
Clients need to support these CAs:
- Amazon Root CA 1
- Starfield Services Root Certificate Authority - G2
- Starfield Class 2 Certification Authority
## Core API Operations
### Function Management Operations
- `CreateFunction` - Create new Lambda function
- `DeleteFunction` - Delete existing function
- `GetFunction` - Retrieve function configuration
- `UpdateFunctionCode` - Update function code
- `UpdateFunctionConfiguration` - Update function settings
- `ListFunctions` - List functions for account
### Invocation Operations
- `Invoke` - Invoke Lambda function synchronously
- `Invoke` with `InvocationType.EVENT` - Asynchronous invocation
### Environment & Configuration
- Environment variable management
- Function configuration updates
- Version and alias management
- Layer management
## Examples Overview
The AWS documentation includes examples for:
- Basic Lambda function creation and invocation
- Function configuration and updates
- Environment variable management
- Function listing and cleanup
- Integration patterns
## Best Practices from Official Docs
- Reuse Lambda clients across invocations
- Set appropriate timeouts matching function requirements
- Use async invocation for fire-and-forget scenarios
- Implement proper error handling for function errors and status codes
- Use environment variables for configuration management
- Version functions for production stability
- Monitor invocations using CloudWatch metrics
- Implement retry logic for transient failures
- Use VPC integration for private resources
- Optimize payload sizes for performance
## Security Considerations
- Use IAM roles with least privilege
- Implement proper Lambda permissions
- Use environment variables for sensitive data
- Enable CloudTrail logging
- Monitor security events with CloudWatch
- Use code signing for production deployments
- Implement proper authentication and authorization