private SSLContext createSSLContext(SSLConfig sslConfig) throws GeneralSecurityException, IOException {
    SSLContext sslContext;
    if (!sslConfig.sslContextProvider.isEmpty()) {
      sslContext = SSLContext.getInstance(sslConfig.sslContextProtocol, sslConfig.sslContextProvider);
    } else {
      sslContext = SSLContext.getInstance(sslConfig.sslContextProtocol);
    }

    SecurityStore keystore =
        new SecurityStore(sslConfig.sslKeystoreType, sslConfig.sslKeystorePath, sslConfig.sslKeystorePassword);
    String kmfAlgorithm = sslConfig.sslKeymanagerAlgorithm.isEmpty() ? KeyManagerFactory.getDefaultAlgorithm()
        : sslConfig.sslKeymanagerAlgorithm;
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
    KeyStore ks = keystore.load();
    String keyPassword = sslConfig.sslKeyPassword.isEmpty() ? keystore.password : sslConfig.sslKeyPassword;
    kmf.init(ks, keyPassword.toCharArray());
    KeyManager[] keyManagers = kmf.getKeyManagers();

    String tmfAlgorithm = sslConfig.sslTrustmanagerAlgorithm.isEmpty() ? TrustManagerFactory.getDefaultAlgorithm()
        : sslConfig.sslTrustmanagerAlgorithm;
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    KeyStore ts = new SecurityStore(sslConfig.sslTruststoreType, sslConfig.sslTruststorePath,
        sslConfig.sslTruststorePassword).load();
    tmf.init(ts);

    sslContext.init(keyManagers, tmf.getTrustManagers(),
        sslConfig.sslSecureRandomAlgorithm.isEmpty() ? new SecureRandom()
            : SecureRandom.getInstance(sslConfig.sslSecureRandomAlgorithm));
    return sslContext;
  }
Create {@link SSLContext} by loading keystore and trustsotre
One factory only has one SSLContext
@param sslConfig the config for setting up the {@link SSLContext}
@return SSLContext
@throws GeneralSecurityException
@throws IOException
ambry-commons/src/main/java/com/github/ambry/commons/JdkSslFactory.java