Skip to content

Commit ddc8c70

Browse files
committed
add verify api client step
1 parent 3453cdf commit ddc8c70

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

org-code-javabuilder/lib/src/main/java/org/code/javabuilder/LambdaRequestHandler.java

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApi;
99
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApiClientBuilder;
1010
import com.amazonaws.services.apigatewaymanagementapi.model.DeleteConnectionRequest;
11+
import com.amazonaws.services.apigatewaymanagementapi.model.GetConnectionRequest;
1112
import com.amazonaws.services.apigatewaymanagementapi.model.GoneException;
1213
import com.amazonaws.services.lambda.runtime.Context;
1314
import com.amazonaws.services.lambda.runtime.RequestHandler;
@@ -49,24 +50,27 @@ public class LambdaRequestHandler implements RequestHandler<Map<String, String>,
4950

5051
// Creating these clients here rather than in the request handler method allows us to use
5152
// provisioned concurrency to decrease cold boot time by 3-10 seconds, depending on the lambda
52-
private static final AmazonApiGatewayManagementApi API_CLIENT =
53-
AmazonApiGatewayManagementApiClientBuilder.standard()
54-
.withEndpointConfiguration(
55-
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
56-
.build();
5753
private static final AmazonSQS SQS_CLIENT = AmazonSQSClientBuilder.defaultClient();
5854
private static final AmazonS3 S3_CLIENT = AmazonS3ClientBuilder.standard().build();
5955

6056
// Controls whether the current invocation session has been initialized. This should be reset on
6157
// every invocation.
6258
private boolean isSessionInitialized = false;
59+
// API Gateway Client. We create this in the constructor so we can recreate it if it goes away for
60+
// some reason.
61+
private AmazonApiGatewayManagementApi apiClient;
6362

6463
public LambdaRequestHandler() {
6564
// create CachedResources once for the entire container.
6665
// This will only be called once in the initial creation of the lambda instance.
6766
// Documentation: https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html
6867
CachedResources.create();
6968
COLD_BOOT_END = Clock.systemUTC().instant();
69+
this.apiClient =
70+
AmazonApiGatewayManagementApiClientBuilder.standard()
71+
.withEndpointConfiguration(
72+
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
73+
.build();
7074
}
7175

7276
/**
@@ -134,7 +138,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
134138
}
135139

136140
final ExceptionHandler exceptionHandler =
137-
new ExceptionHandler(outputAdapter, new AWSSystemExitHelper(connectionId, API_CLIENT));
141+
new ExceptionHandler(outputAdapter, new AWSSystemExitHelper(connectionId, this.apiClient));
138142
final TempDirectoryManager tempDirectoryManager = new AWSTempDirectoryManager();
139143

140144
CodeExecutionManager codeExecutionManager = null;
@@ -150,7 +154,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
150154
// Create and start thread that that will notify us if we're nearing the timeout limit
151155
timeoutNotifierThread =
152156
this.createTimeoutThread(
153-
context, outputAdapter, codeExecutionManager, connectionId, API_CLIENT);
157+
context, outputAdapter, codeExecutionManager, connectionId, this.apiClient);
154158
timeoutNotifierThread.start();
155159

156160
// Initialize and start code execution
@@ -162,7 +166,7 @@ public String handleRequest(Map<String, String> lambdaInput, Context context) {
162166
if (timeoutNotifierThread != null) {
163167
timeoutNotifierThread.interrupt();
164168
}
165-
this.shutDown(codeExecutionManager, connectionId, API_CLIENT);
169+
this.shutDown(codeExecutionManager, connectionId, this.apiClient);
166170
}
167171

168172
return "done";
@@ -188,6 +192,8 @@ private void initialize(Map<String, String> lambdaInput, String connectionId, Co
188192
// /opt is the folder all layer files go into.
189193
props.put("sun.awt.fontconfig", "/opt/fontconfig.properties");
190194

195+
this.verifyApiClient(connectionId);
196+
191197
this.isSessionInitialized = true;
192198
}
193199

@@ -214,7 +220,7 @@ private OutputAdapter createOutputAdapter(Map<String, String> lambdaInput)
214220
if (connectionId == null) {
215221
throw new InternalFacingException(INVALID_INPUT, new Exception("Missing connection ID"));
216222
}
217-
final AWSOutputAdapter awsOutputAdapter = new AWSOutputAdapter(connectionId, API_CLIENT);
223+
final AWSOutputAdapter awsOutputAdapter = new AWSOutputAdapter(connectionId, this.apiClient);
218224

219225
try {
220226
final ExecutionType executionType = ExecutionType.valueOf(lambdaInput.get("executionType"));
@@ -270,7 +276,7 @@ private CodeExecutionManager createExecutionManager(
270276
compileList,
271277
tempDirectoryManager,
272278
contentManager,
273-
new AWSSystemExitHelper(connectionId, API_CLIENT));
279+
new AWSSystemExitHelper(connectionId, this.apiClient));
274280
}
275281

276282
/**
@@ -371,4 +377,20 @@ private void cleanUpAWSResources(String connectionId, AmazonApiGatewayManagement
371377
Logger.getLogger(MAIN_LOGGER).removeHandler(allHandlers[i]);
372378
}
373379
}
380+
381+
private void verifyApiClient(String connectionId) {
382+
GetConnectionRequest connectionRequest =
383+
new GetConnectionRequest().withConnectionId(connectionId);
384+
try {
385+
this.apiClient.getConnection(connectionRequest);
386+
} catch (IllegalStateException e) {
387+
// This can occur if the api client has been shut down, which we have seen happen on occasion.
388+
// Recreate the api client in this case.
389+
this.apiClient =
390+
AmazonApiGatewayManagementApiClientBuilder.standard()
391+
.withEndpointConfiguration(
392+
new AwsClientBuilder.EndpointConfiguration(API_ENDPOINT, "us-east-1"))
393+
.build();
394+
}
395+
}
374396
}

0 commit comments

Comments
 (0)