0

I have a JAVA 8 AWS lambda function that has some pretty expensive setup when the container is first spun up. It must make calls to pull various credentials/cacerts. I would like to cache this set up (the output of which is an SSLContext object that is used for making calls to another api).

I have not had to do this before, and my question that I cannot seem to find an answer for is this:

Are there any issues reusing the SSLContext object over and over again while the Lambda Container is alive? this could be 15 minutes or 5 hours, or 2 days, etc.. as long as there is traffic coming through it, it will be alive.

None of the credentials will change, and the SSLContext object would be identical between all invocations.

Do SSLContext objects have a TTL? The code to create the SSLConext is fairly boilerplate. This method is called after I have done the expensive pulls to get the certs/cred and I want to cache this SSLContext object:

public SSLContext getContext(){
        KeyStore clientStore = KeyStore.getInstance(KEY_INSTANCE);
        keyStoreInputstream = //GET STREAM
        clientStore.load(keyStoreInputstream, caCertCred.toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientStore, KEY.toCharArray());
        KeyManager[] kms = kmf.getKeyManagers();

        trustStoreInputStream =  //GET STREAM
        KeyStore trustStore = KeyStore.getInstance(TRUST_INSTANCE);
        trustStore.load(trustStoreInputStream, caCertCred.toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        TrustManager[] tms = tmf.getTrustManagers();

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kms, tms, new SecureRandom());
        return sslContext;

}

  • 1
    1) Have you tried this? It should work and there is no documentation I could find that indicates any sort of TTL. 2) Have you timed how expensive these calls are? If you're saving 100 ms on a 3 minute run then you'll have to decide if it's worth it. My feeling is that these calls are do not take too long. But don't guess - time them. – stdunbar Sep 17 '20 at 19:59

1 Answers1

0

The short answer: Use a class-level variable.

In AWS Lambda, class level variables are "global" variables. So if you declare a variable outside the handleRequest(...) method, the Lambda container will keep that variable initialized with the same value. When the lambda function executes again, you just have to reuse the variable as it is.

Here's an example of how it works:

public class LambdaExample implements RequestStreamHandler {

    private LambdaLogger logger;
    private SSLContext sslContext;

    @Override
    public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
        logger = context.getLogger();

        // do some work


        if(sslContext == null) {
            // this means SSLContext needs to be initialized - probably a new container
            initSslContext();
        } else {
            // this means SSLContext is already initialized - just use it as it is
        }

        // use SSLContext
    }

    private void initSslContext() {
        // note: you need to create the KeyStore, KeyManagerFactory
        //  and re-initialize the SSLContext here because it's null
    }
}

Note:
Usually, global variables have some downside but I think in your case, it wouldn't create any issues. You can watch the following video to really understand how global variables work in AWS Lambda.
https://www.youtube.com/watch?v=-P7oB8NQpiI

ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73