66package com .amazonaws .services .lambda .runtime .api .client ;
77
88import com .amazonaws .services .lambda .runtime .LambdaLogger ;
9+ import com .amazonaws .services .lambda .runtime .api .client .LambdaRequestHandler .UserFaultHandler ;
10+ import com .amazonaws .services .lambda .runtime .api .client .logging .FramedTelemetryLogSink ;
911import com .amazonaws .services .lambda .runtime .api .client .logging .LambdaContextLogger ;
12+ import com .amazonaws .services .lambda .runtime .api .client .logging .LogSink ;
1013import com .amazonaws .services .lambda .runtime .api .client .logging .StdOutLogSink ;
11- import com .amazonaws .services .lambda .runtime .api .client .util . EnvReader ;
12- import com .amazonaws .services .lambda .runtime .api .client .util . EnvWriter ;
14+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi . InvocationRequest ;
15+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi . LambdaRuntimeClient ;
1316import com .amazonaws .services .lambda .runtime .api .client .util .LambdaOutputStream ;
1417import com .amazonaws .services .lambda .runtime .api .client .util .UnsafeUtil ;
1518import com .amazonaws .services .lambda .runtime .serialization .PojoSerializer ;
1619import com .amazonaws .services .lambda .runtime .serialization .factories .GsonFactory ;
1720import com .amazonaws .services .lambda .runtime .serialization .factories .JacksonFactory ;
1821import com .amazonaws .services .lambda .runtime .serialization .util .ReflectUtil ;
19- import com .amazonaws .services .lambda .runtime .api .client .LambdaRequestHandler .UserFaultHandler ;
20- import com .amazonaws .services .lambda .runtime .api .client .logging .FramedTelemetryLogSink ;
21- import com .amazonaws .services .lambda .runtime .api .client .logging .LogSink ;
22- import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .InvocationRequest ;
23- import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .LambdaRuntimeClient ;
2422
2523import java .io .ByteArrayOutputStream ;
2624import java .io .File ;
@@ -57,6 +55,10 @@ public class AWSLambda {
5755
5856 private static final String DEFAULT_NEGATIVE_CACHE_TTL = "1" ;
5957
58+ // System property for Lambda tracing, see aws-xray-sdk-java/LambdaSegmentContext
59+ // https://github.com/aws/aws-xray-sdk-java/blob/2f467e50db61abb2ed2bd630efc21bddeabd64d9/aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/contexts/LambdaSegmentContext.java#L39-L40
60+ private static final String LAMBDA_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader" ;
61+
6062 static {
6163 // Override the disabledAlgorithms setting to match configuration for openjdk8-u181.
6264 // This is to keep DES ciphers around while we deploying security updates.
@@ -68,9 +70,9 @@ public class AWSLambda {
6870 // The ca-certificates package provides /etc/pki/java/cacerts which becomes the symlink destination
6971 // of $java_home/lib/security/cacerts when java is installed in the chroot. Given that java is provided
7072 // in /var/lang as opposed to installed in the chroot, this brings it closer.
71- if (System .getProperty (TRUST_STORE_PROPERTY ) == null ) {
73+ if (System .getProperty (TRUST_STORE_PROPERTY ) == null ) {
7274 final File systemCacerts = new File ("/etc/pki/java/cacerts" );
73- if (systemCacerts .exists () && systemCacerts .isFile ()) {
75+ if (systemCacerts .exists () && systemCacerts .isFile ()) {
7476 System .setProperty (TRUST_STORE_PROPERTY , systemCacerts .getPath ());
7577 }
7678 }
@@ -114,9 +116,9 @@ private static LambdaRequestHandler findRequestHandler(final String handlerStrin
114116 final LambdaRequestHandler requestHandler = EventHandlerLoader .loadEventHandler (handlerInfo );
115117 // if loading the handler failed and the failure is fatal (for e.g. the constructor threw an exception)
116118 // we want to report this as an init error rather than deferring to the first invoke.
117- if (requestHandler instanceof UserFaultHandler ) {
118- UserFault userFault =((UserFaultHandler ) requestHandler ).fault ;
119- if (userFault .fatal ) {
119+ if (requestHandler instanceof UserFaultHandler ) {
120+ UserFault userFault = ((UserFaultHandler ) requestHandler ).fault ;
121+ if (userFault .fatal ) {
120122 throw userFault ;
121123 }
122124 }
@@ -135,7 +137,7 @@ public static void setupRuntimeLogger(LambdaLogger lambdaLogger)
135137
136138 public static String getEnvOrExit (String envVariableName ) {
137139 String value = System .getenv (envVariableName );
138- if (value == null ) {
140+ if (value == null ) {
139141 System .err .println ("Could not get environment variable " + envVariableName );
140142 System .exit (-1 );
141143 }
@@ -150,17 +152,17 @@ public static String getEnvOrExit(String envVariableName) {
150152 private static FileDescriptor intToFd (int fd ) throws RuntimeException {
151153 try {
152154 Class <FileDescriptor > clazz = FileDescriptor .class ;
153- Constructor <FileDescriptor > c = clazz .getDeclaredConstructor (new Class <?>[] { Integer .TYPE });
155+ Constructor <FileDescriptor > c = clazz .getDeclaredConstructor (new Class <?>[]{ Integer .TYPE });
154156 c .setAccessible (true );
155157 return c .newInstance (new Integer (fd ));
156- } catch (Exception e ) {
158+ } catch (Exception e ) {
157159 throw new RuntimeException (e );
158160 }
159161 }
160162
161163 private static LogSink createLogSink () {
162164 final String fdStr = System .getenv ("_LAMBDA_TELEMETRY_LOG_FD" );
163- if (fdStr == null ) {
165+ if (fdStr == null ) {
164166 return new StdOutLogSink ();
165167 }
166168
@@ -196,13 +198,6 @@ private static void startRuntime(String handler, LambdaLogger lambdaLogger) thro
196198 String runtimeApi = getEnvOrExit (ReservedRuntimeEnvironmentVariables .AWS_LAMBDA_RUNTIME_API );
197199 LambdaRuntimeClient runtimeClient = new LambdaRuntimeClient (runtimeApi );
198200
199- EnvReader envReader = new EnvReader ();
200- try (EnvWriter envWriter = new EnvWriter (envReader )) {
201- envWriter .unsetLambdaInternalEnv ();
202- envWriter .setupEnvironmentCredentials ();
203- envWriter .setupAwsExecutionEnv ();
204- }
205-
206201 String taskRoot = System .getProperty ("user.dir" );
207202 String libRoot = "/opt/java" ;
208203 // Make system classloader the customer classloader's parent to ensure any aws-lambda-java-core classes
@@ -224,44 +219,42 @@ private static void startRuntime(String handler, LambdaLogger lambdaLogger) thro
224219 return ;
225220 }
226221
227- try (EnvWriter envWriter = new EnvWriter (envReader )) {
228- boolean shouldExit = false ;
229- while (!shouldExit ) {
230- UserFault userFault = null ;
231- InvocationRequest request = runtimeClient .waitForNextInvocation ();
232- if (request .getXrayTraceId () != null ) {
233- envWriter .modifyEnv (m -> m .put ("_X_AMZN_TRACE_ID" , request .getXrayTraceId ()));
234- } else {
235- envWriter .modifyEnv (m -> m .remove ("_X_AMZN_TRACE_ID" ));
236- }
222+ boolean shouldExit = false ;
223+ while (!shouldExit ) {
224+ UserFault userFault = null ;
225+ InvocationRequest request = runtimeClient .waitForNextInvocation ();
226+ if (request .getXrayTraceId () != null ) {
227+ System .setProperty (LAMBDA_TRACE_HEADER_PROP , request .getXrayTraceId ());
228+ } else {
229+ System .clearProperty (LAMBDA_TRACE_HEADER_PROP );
230+ }
237231
238- ByteArrayOutputStream payload ;
239- try {
240- payload = requestHandler .call (request );
241- // TODO calling payload.toByteArray() creates a new copy of the underlying buffer
242- runtimeClient .postInvocationResponse (request .getId (), payload .toByteArray ());
243- } catch (UserFault f ) {
244- userFault = f ;
245- UserFault .filterStackTrace (f );
246- payload = new ByteArrayOutputStream (1024 );
247- Failure failure = new Failure (f );
248- GsonFactory .getInstance ().getSerializer (Failure .class ).toJson (failure , payload );
249- shouldExit = f .fatal ;
250- runtimeClient .postInvocationError (request .getId (), payload .toByteArray (), failure .getErrorType ());
251- } catch (Throwable t ) {
252- UserFault .filterStackTrace (t );
253- userFault = UserFault .makeUserFault (t );
254- payload = new ByteArrayOutputStream (1024 );
255- Failure failure = new Failure (t );
256- GsonFactory .getInstance ().getSerializer (Failure .class ).toJson (failure , payload );
257- // These two categories of errors are considered fatal.
258- shouldExit = Failure .isInvokeFailureFatal (t );
259- runtimeClient .postInvocationError (request .getId (), payload .toByteArray (), failure .getErrorType (),
260- serializeAsXRayJson (t ));
261- } finally {
262- if (userFault != null ) {
263- lambdaLogger .log (userFault .reportableError ());
264- }
232+ ByteArrayOutputStream payload ;
233+ try {
234+ payload = requestHandler .call (request );
235+ // TODO calling payload.toByteArray() creates a new copy of the underlying buffer
236+ runtimeClient .postInvocationResponse (request .getId (), payload .toByteArray ());
237+ } catch (UserFault f ) {
238+ userFault = f ;
239+ UserFault .filterStackTrace (f );
240+ payload = new ByteArrayOutputStream (1024 );
241+ Failure failure = new Failure (f );
242+ GsonFactory .getInstance ().getSerializer (Failure .class ).toJson (failure , payload );
243+ shouldExit = f .fatal ;
244+ runtimeClient .postInvocationError (request .getId (), payload .toByteArray (), failure .getErrorType ());
245+ } catch (Throwable t ) {
246+ UserFault .filterStackTrace (t );
247+ userFault = UserFault .makeUserFault (t );
248+ payload = new ByteArrayOutputStream (1024 );
249+ Failure failure = new Failure (t );
250+ GsonFactory .getInstance ().getSerializer (Failure .class ).toJson (failure , payload );
251+ // These two categories of errors are considered fatal.
252+ shouldExit = Failure .isInvokeFailureFatal (t );
253+ runtimeClient .postInvocationError (request .getId (), payload .toByteArray (), failure .getErrorType (),
254+ serializeAsXRayJson (t ));
255+ } finally {
256+ if (userFault != null ) {
257+ lambdaLogger .log (userFault .reportableError ());
265258 }
266259 }
267260 }
@@ -270,15 +263,14 @@ private static void startRuntime(String handler, LambdaLogger lambdaLogger) thro
270263 private static PojoSerializer <XRayErrorCause > xRayErrorCauseSerializer ;
271264
272265 /**
273- *
274266 * @param throwable throwable to convert
275267 * @return json as string expected by XRay's web console. On conversion failure, returns null.
276268 */
277269 private static String serializeAsXRayJson (Throwable throwable ) {
278270 try {
279271 final OutputStream outputStream = new ByteArrayOutputStream ();
280272 final XRayErrorCause cause = new XRayErrorCause (throwable );
281- if (xRayErrorCauseSerializer == null ) {
273+ if (xRayErrorCauseSerializer == null ) {
282274 xRayErrorCauseSerializer = JacksonFactory .getInstance ().getSerializer (XRayErrorCause .class );
283275 }
284276 xRayErrorCauseSerializer .toJson (cause , outputStream );
@@ -287,5 +279,4 @@ private static String serializeAsXRayJson(Throwable throwable) {
287279 return null ;
288280 }
289281 }
290-
291282}
0 commit comments