Rewrite rest-client to use Jersey 2.x API
[aai/rest-client.git] / src / main / java / org / onap / aai / restclient / rest / RestClientBuilder.java
index 26c5fdf..38a8558 100644 (file)
@@ -22,281 +22,262 @@ package org.onap.aai.restclient.rest;
 \r
 import java.io.FileInputStream;\r
 import java.security.KeyStore;\r
-import java.security.cert.X509Certificate;\r
-\r
-import javax.net.ssl.HostnameVerifier;\r
 import javax.net.ssl.KeyManagerFactory;\r
 import javax.net.ssl.SSLContext;\r
 import javax.net.ssl.SSLSession;\r
 import javax.net.ssl.TrustManager;\r
-import javax.net.ssl.X509TrustManager;\r
-\r
+import javax.ws.rs.client.Client;\r
+import javax.ws.rs.client.ClientBuilder;\r
+import org.glassfish.jersey.client.ClientProperties;\r
 import org.onap.aai.restclient.enums.RestAuthenticationMode;\r
 \r
-import com.sun.jersey.api.client.Client;\r
-import com.sun.jersey.api.client.config.ClientConfig;\r
-import com.sun.jersey.api.client.config.DefaultClientConfig;\r
-import com.sun.jersey.client.urlconnection.HTTPSProperties;\r
\r
 /**\r
- * This is a generic REST Client builder with flexible security validation. Sometimes it's nice to\r
- * be able to disable server chain cert validation and hostname validation to work-around lab\r
- * issues, but at the same time be able to provide complete validation with client cert + hostname +\r
- * server cert chain validation. I used the ModelLoader REST client as a base and merged in the TSUI\r
- * client I wrote which also validates the server hostname and server certificate chain.\r
+ * This is a generic REST Client builder with flexible security validation. Sometimes it's nice to be able to disable\r
+ * server chain cert validation and hostname validation to work-around lab issues, but at the same time be able to\r
+ * provide complete validation with client cert + hostname + server cert chain validation. I used the ModelLoader REST\r
+ * client as a base and merged in the TSUI client I wrote which also validates the server hostname and server\r
+ * certificate chain.\r
  */\r
 public class RestClientBuilder {\r
 \r
-  public static final boolean DEFAULT_VALIDATE_SERVER_HOST = false;\r
-  public static final boolean DEFAULT_VALIDATE_CERT_CHAIN = false;\r
-  public static final String DEFAULT_CLIENT_CERT_FILENAME = null;\r
-  public static final String DEFAULT_CERT_PASSWORD = null;\r
-  public static final String DEFAULT_TRUST_STORE_FILENAME = null;\r
-  public static final int DEFAULT_CONNECT_TIMEOUT_MS = 60000;\r
-  public static final int DEFAULT_READ_TIMEOUT_MS = 60000;\r
-  public static final RestAuthenticationMode DEFAULT_AUTH_MODE = RestAuthenticationMode.SSL_CERT;\r
-  public static final String DEFAULT_BASIC_AUTH_USERNAME = "";\r
-  public static final String DEFAULT_BASIC_AUTH_PASSWORD = "";\r
-  public static final String DEFAULT_SSL_PROTOCOL = "TLS";\r
-\r
-  private static final String KEYSTORE_ALGORITHM = "SunX509";\r
-  private static final String KEYSTORE_TYPE = "PKCS12";\r
-  private static final String TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";\r
-\r
-  private boolean validateServerHostname;\r
-  private boolean validateServerCertChain;\r
-  private String clientCertFileName;\r
-  private String clientCertPassword;\r
-  private String truststoreFilename;\r
-  private int connectTimeoutInMs;\r
-  private int readTimeoutInMs;\r
-  private RestAuthenticationMode authenticationMode;\r
-  private String basicAuthUsername;\r
-  private String basicAuthPassword;\r
-  private String sslProtocol;\r
-\r
-  /**\r
-   * Rest Client Builder.\r
-   */\r
-  public RestClientBuilder() {\r
-    validateServerHostname = DEFAULT_VALIDATE_SERVER_HOST;\r
-    validateServerCertChain = DEFAULT_VALIDATE_CERT_CHAIN;\r
-    clientCertFileName = DEFAULT_CLIENT_CERT_FILENAME;\r
-    clientCertPassword = DEFAULT_CERT_PASSWORD;\r
-    truststoreFilename = DEFAULT_TRUST_STORE_FILENAME;\r
-    connectTimeoutInMs = DEFAULT_CONNECT_TIMEOUT_MS;\r
-    readTimeoutInMs = DEFAULT_READ_TIMEOUT_MS;\r
-    authenticationMode = DEFAULT_AUTH_MODE;\r
-    basicAuthUsername = DEFAULT_BASIC_AUTH_USERNAME;\r
-    basicAuthPassword = DEFAULT_BASIC_AUTH_PASSWORD;\r
-    sslProtocol = DEFAULT_SSL_PROTOCOL;\r
-  }\r
-\r
-  public boolean isValidateServerHostname() {\r
-    return validateServerHostname;\r
-  }\r
-\r
-  public void setValidateServerHostname(boolean validateServerHostname) {\r
-    this.validateServerHostname = validateServerHostname;\r
-  }\r
-\r
-  public boolean isValidateServerCertChain() {\r
-    return validateServerCertChain;\r
-  }\r
-\r
-  public void setValidateServerCertChain(boolean validateServerCertChain) {\r
-    this.validateServerCertChain = validateServerCertChain;\r
-  }\r
-\r
-  public String getClientCertFileName() {\r
-    return clientCertFileName;\r
-  }\r
-\r
-  public void setClientCertFileName(String clientCertFileName) {\r
-    this.clientCertFileName = clientCertFileName;\r
-  }\r
-\r
-  public String getClientCertPassword() {\r
-    return clientCertPassword;\r
-  }\r
-\r
-  public void setClientCertPassword(String clientCertPassword) {\r
-    this.clientCertPassword = clientCertPassword;\r
-  }\r
-\r
-  public String getTruststoreFilename() {\r
-    return truststoreFilename;\r
-  }\r
-\r
-  public void setTruststoreFilename(String truststoreFilename) {\r
-    this.truststoreFilename = truststoreFilename;\r
-  }\r
-\r
-  public int getConnectTimeoutInMs() {\r
-    return connectTimeoutInMs;\r
-  }\r
-\r
-  public void setConnectTimeoutInMs(int connectTimeoutInMs) {\r
-    this.connectTimeoutInMs = connectTimeoutInMs;\r
-  }\r
-\r
-  public int getReadTimeoutInMs() {\r
-    return readTimeoutInMs;\r
-  }\r
-\r
-  public void setReadTimeoutInMs(int readTimeoutInMs) {\r
-    this.readTimeoutInMs = readTimeoutInMs;\r
-  }\r
-\r
-  public RestAuthenticationMode getAuthenticationMode() {\r
-    return authenticationMode;\r
-  }\r
-\r
-  public void setAuthenticationMode(RestAuthenticationMode authenticationMode) {\r
-    this.authenticationMode = authenticationMode;\r
-  }\r
-\r
-  public String getBasicAuthUsername() {\r
-    return basicAuthUsername;\r
-  }\r
-\r
-  public void setBasicAuthUsername(String basicAuthUsername) {\r
-    this.basicAuthUsername = basicAuthUsername;\r
-  }\r
-\r
-  public String getBasicAuthPassword() {\r
-    return basicAuthPassword;\r
-  }\r
-\r
-  public void setBasicAuthPassword(String basicAuthPassword) {\r
-    this.basicAuthPassword = basicAuthPassword;\r
-  }\r
-\r
-  public String getSslProtocol() {\r
-    return sslProtocol;\r
-  }\r
-\r
-  public void setSslProtocol(String sslProtocol) {\r
-    this.sslProtocol = sslProtocol;\r
-  }\r
-\r
-  /**\r
-   * Returns Client configured for SSL\r
-   */\r
-  public Client getClient() throws Exception {\r
-\r
-    switch (authenticationMode) {\r
-      case SSL_BASIC:\r
-      case SSL_CERT:\r
-        return getClient(true);\r
-\r
-      default:\r
-        // return basic non-authenticating HTTP client\r
-        return getClient(false);\r
+    public static final boolean DEFAULT_VALIDATE_SERVER_HOST = false;\r
+    public static final boolean DEFAULT_VALIDATE_CERT_CHAIN = false;\r
+    public static final String DEFAULT_CLIENT_CERT_FILENAME = null;\r
+    public static final String DEFAULT_CERT_PASSWORD = null;\r
+    public static final String DEFAULT_TRUST_STORE_FILENAME = null;\r
+    public static final int DEFAULT_CONNECT_TIMEOUT_MS = 60000;\r
+    public static final int DEFAULT_READ_TIMEOUT_MS = 60000;\r
+    public static final RestAuthenticationMode DEFAULT_AUTH_MODE = RestAuthenticationMode.SSL_CERT;\r
+    public static final String DEFAULT_BASIC_AUTH_USERNAME = "";\r
+    public static final String DEFAULT_BASIC_AUTH_PASSWORD = "";\r
+    public static final String DEFAULT_SSL_PROTOCOL = "TLS";\r
+\r
+    private static final String KEYSTORE_ALGORITHM = "SunX509";\r
+    private static final String KEYSTORE_TYPE = "PKCS12";\r
+    private static final String TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";\r
+\r
+    private boolean validateServerHostname;\r
+    private boolean validateServerCertChain;\r
+    private String clientCertFileName;\r
+    private String clientCertPassword;\r
+    private String truststoreFilename;\r
+    private int connectTimeoutInMs;\r
+    private int readTimeoutInMs;\r
+    private RestAuthenticationMode authenticationMode;\r
+    private String basicAuthUsername;\r
+    private String basicAuthPassword;\r
+    private String sslProtocol;\r
+\r
+    /**\r
+     * Rest Client Builder.\r
+     */\r
+    public RestClientBuilder() {\r
+        validateServerHostname = DEFAULT_VALIDATE_SERVER_HOST;\r
+        validateServerCertChain = DEFAULT_VALIDATE_CERT_CHAIN;\r
+        clientCertFileName = DEFAULT_CLIENT_CERT_FILENAME;\r
+        clientCertPassword = DEFAULT_CERT_PASSWORD;\r
+        truststoreFilename = DEFAULT_TRUST_STORE_FILENAME;\r
+        connectTimeoutInMs = DEFAULT_CONNECT_TIMEOUT_MS;\r
+        readTimeoutInMs = DEFAULT_READ_TIMEOUT_MS;\r
+        authenticationMode = DEFAULT_AUTH_MODE;\r
+        basicAuthUsername = DEFAULT_BASIC_AUTH_USERNAME;\r
+        basicAuthPassword = DEFAULT_BASIC_AUTH_PASSWORD;\r
+        sslProtocol = DEFAULT_SSL_PROTOCOL;\r
+    }\r
+\r
+    public boolean isValidateServerHostname() {\r
+        return validateServerHostname;\r
+    }\r
+\r
+    public void setValidateServerHostname(boolean validateServerHostname) {\r
+        this.validateServerHostname = validateServerHostname;\r
+    }\r
+\r
+    public boolean isValidateServerCertChain() {\r
+        return validateServerCertChain;\r
+    }\r
+\r
+    public void setValidateServerCertChain(boolean validateServerCertChain) {\r
+        this.validateServerCertChain = validateServerCertChain;\r
+    }\r
+\r
+    public String getClientCertFileName() {\r
+        return clientCertFileName;\r
+    }\r
+\r
+    public void setClientCertFileName(String clientCertFileName) {\r
+        this.clientCertFileName = clientCertFileName;\r
+    }\r
+\r
+    public String getClientCertPassword() {\r
+        return clientCertPassword;\r
+    }\r
+\r
+    public void setClientCertPassword(String clientCertPassword) {\r
+        this.clientCertPassword = clientCertPassword;\r
+    }\r
+\r
+    public String getTruststoreFilename() {\r
+        return truststoreFilename;\r
+    }\r
+\r
+    public void setTruststoreFilename(String truststoreFilename) {\r
+        this.truststoreFilename = truststoreFilename;\r
+    }\r
+\r
+    public int getConnectTimeoutInMs() {\r
+        return connectTimeoutInMs;\r
+    }\r
+\r
+    public void setConnectTimeoutInMs(int connectTimeoutInMs) {\r
+        this.connectTimeoutInMs = connectTimeoutInMs;\r
     }\r
 \r
-  }\r
-\r
-  protected void setupSecureSocketLayerClientConfig(ClientConfig clientConfig) throws Exception {\r
-    // Check to see if we need to perform proper validation of\r
-    // the certificate chains.\r
-    TrustManager[] trustAllCerts = null;\r
-      if (truststoreFilename != null) {\r
-        System.setProperty(TRUST_STORE_PROPERTY, truststoreFilename);\r
-      } else {\r
-        throw new IllegalArgumentException("Trust store filename must be set!");\r
-      }\r
-\r
-    // Set up the SSL context, keystore, etc. to use for our connection\r
-    // to the AAI.\r
-    SSLContext ctx = SSLContext.getInstance(sslProtocol);\r
-    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM);\r
-    KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);\r
-\r
-    char[] pwd = null;\r
-    if (clientCertPassword != null) {\r
-      pwd = clientCertPassword.toCharArray();\r
+    public int getReadTimeoutInMs() {\r
+        return readTimeoutInMs;\r
     }\r
 \r
-    if (clientCertFileName != null) {\r
-      FileInputStream fin = new FileInputStream(clientCertFileName);\r
+    public void setReadTimeoutInMs(int readTimeoutInMs) {\r
+        this.readTimeoutInMs = readTimeoutInMs;\r
+    }\r
+\r
+    public RestAuthenticationMode getAuthenticationMode() {\r
+        return authenticationMode;\r
+    }\r
 \r
-      // Load the keystore and initialize the key manager factory.\r
-      ks.load(fin, pwd);\r
-      kmf.init(ks, pwd);\r
+    public void setAuthenticationMode(RestAuthenticationMode authenticationMode) {\r
+        this.authenticationMode = authenticationMode;\r
+    }\r
 \r
-      ctx.init(kmf.getKeyManagers(), trustAllCerts, null);\r
-    } else {\r
-      ctx.init(null, trustAllCerts, null);\r
+    public String getBasicAuthUsername() {\r
+        return basicAuthUsername;\r
     }\r
 \r
-    // Are we performing validation of the server host name?\r
-    if (validateServerHostname) {\r
-      clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,\r
-          new HTTPSProperties(null, ctx));\r
-\r
-    } else {\r
-      clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,\r
-          new HTTPSProperties(new HostnameVerifier() {\r
-            @Override\r
-            public boolean verify(String str, SSLSession sslSession) {\r
-              return true;\r
-            }\r
-          }, ctx));\r
+    public void setBasicAuthUsername(String basicAuthUsername) {\r
+        this.basicAuthUsername = basicAuthUsername;\r
     }\r
-  }\r
 \r
+    public String getBasicAuthPassword() {\r
+        return basicAuthPassword;\r
+    }\r
 \r
-  /**\r
-   * Returns client instance\r
-   * \r
-   * @param useSsl - used to configure the client with an ssl-context or just plain http\r
-   */\r
-  protected Client getClient(boolean useSsl) throws Exception {\r
+    public void setBasicAuthPassword(String basicAuthPassword) {\r
+        this.basicAuthPassword = basicAuthPassword;\r
+    }\r
 \r
-    ClientConfig clientConfig = new DefaultClientConfig();\r
+    public String getSslProtocol() {\r
+        return sslProtocol;\r
+    }\r
 \r
-    if (useSsl) {\r
-      setupSecureSocketLayerClientConfig(clientConfig);\r
+    public void setSslProtocol(String sslProtocol) {\r
+        this.sslProtocol = sslProtocol;\r
     }\r
 \r
-    // Finally, create and initialize our client...\r
-    Client client = null;\r
-    client = Client.create(clientConfig);\r
-    client.setConnectTimeout(connectTimeoutInMs);\r
-    client.setReadTimeout(readTimeoutInMs);\r
-\r
-    // ...and return it to the caller.\r
-    return client;\r
-  }\r
-\r
-  public String getBasicAuthenticationCredentials() {\r
-\r
-    String usernameAndPassword = getBasicAuthUsername() + ":" + getBasicAuthPassword();\r
-    return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());\r
-  }\r
-\r
-  /* \r
-   * Added a little bit of logic to obfuscate passwords that could be logged out\r
-   * (non-Javadoc)\r
-   * @see java.lang.Object#toString()\r
-   */\r
-  @Override\r
-  public String toString() {\r
-    return "RestClientBuilder [validateServerHostname=" + validateServerHostname\r
-        + ", validateServerCertChain=" + validateServerCertChain + ", "\r
-        + (clientCertFileName != null ? "clientCertFileName=" + clientCertFileName + ", " : "")\r
-        + (clientCertPassword != null\r
-            ? "clientCertPassword="\r
-                + java.util.Base64.getEncoder().encodeToString(clientCertPassword.getBytes()) + ", "\r
-            : "")\r
-        + (truststoreFilename != null ? "truststoreFilename=" + truststoreFilename + ", " : "")\r
-        + "connectTimeoutInMs=" + connectTimeoutInMs + ", readTimeoutInMs=" + readTimeoutInMs + ", "\r
-        + (authenticationMode != null ? "authenticationMode=" + authenticationMode + ", " : "")\r
-        + (basicAuthUsername != null ? "basicAuthUsername=" + basicAuthUsername + ", " : "")\r
-        + (basicAuthPassword != null ? "basicAuthPassword="\r
-            + java.util.Base64.getEncoder().encodeToString(basicAuthPassword.getBytes()) : "")\r
-        + "]";\r
-  }\r
+    /**\r
+     * Returns Client configured for SSL\r
+     */\r
+    public Client getClient() throws Exception {\r
+\r
+        switch (authenticationMode) {\r
+            case SSL_BASIC:\r
+            case SSL_CERT:\r
+                return getClient(true);\r
+\r
+            default:\r
+                // return basic non-authenticating HTTP client\r
+                return getClient(false);\r
+        }\r
+\r
+    }\r
+\r
+    protected void setupSecureSocketLayerClientConfig(ClientBuilder builder) throws Exception {\r
+        // Check to see if we need to perform proper validation of\r
+        // the certificate chains.\r
+        TrustManager[] trustAllCerts = null;\r
+        if (truststoreFilename != null) {\r
+            System.setProperty(TRUST_STORE_PROPERTY, truststoreFilename);\r
+        } else {\r
+            throw new IllegalArgumentException("Trust store filename must be set!");\r
+        }\r
+\r
+        // Set up the SSL context, keystore, etc. to use for our connection\r
+        // to the AAI.\r
+        SSLContext ctx = SSLContext.getInstance(sslProtocol);\r
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM);\r
+        KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);\r
+\r
+        char[] pwd = null;\r
+        if (clientCertPassword != null) {\r
+            pwd = clientCertPassword.toCharArray();\r
+        }\r
+\r
+        if (clientCertFileName != null) {\r
+            FileInputStream fin = new FileInputStream(clientCertFileName);\r
+\r
+            // Load the keystore and initialize the key manager factory.\r
+            ks.load(fin, pwd);\r
+            kmf.init(ks, pwd);\r
+\r
+            ctx.init(kmf.getKeyManagers(), trustAllCerts, null);\r
+        } else {\r
+            ctx.init(null, trustAllCerts, null);\r
+        }\r
+\r
+        builder.sslContext(ctx);\r
+\r
+        // Are we performing validation of the server host name?\r
+        if (!validateServerHostname) {\r
+            builder.hostnameVerifier((String str, SSLSession sslSession) -> true);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns client instance\r
+     *\r
+     * @param useSsl - used to configure the client with an ssl-context or just plain http\r
+     */\r
+    protected Client getClient(boolean useSsl) throws Exception {\r
+\r
+        // Finally, create and initialize our client...\r
+        ClientBuilder builder = ClientBuilder.newBuilder();\r
+        if (useSsl) {\r
+            setupSecureSocketLayerClientConfig(builder);\r
+        }\r
+        Client client = builder.build();\r
+        client.property(ClientProperties.CONNECT_TIMEOUT, connectTimeoutInMs);\r
+        client.property(ClientProperties.READ_TIMEOUT, readTimeoutInMs);\r
+\r
+        // ...and return it to the caller.\r
+        return client;\r
+    }\r
+\r
+    public String getBasicAuthenticationCredentials() {\r
+\r
+        String usernameAndPassword = getBasicAuthUsername() + ":" + getBasicAuthPassword();\r
+        return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());\r
+    }\r
+\r
+    /*\r
+     * Added a little bit of logic to obfuscate passwords that could be logged out (non-Javadoc)\r
+     * \r
+     * @see java.lang.Object#toString()\r
+     */\r
+    @Override\r
+    public String toString() {\r
+        return "RestClientBuilder [validateServerHostname=" + validateServerHostname + ", validateServerCertChain="\r
+                + validateServerCertChain + ", "\r
+                + (clientCertFileName != null ? "clientCertFileName=" + clientCertFileName + ", " : "")\r
+                + (clientCertPassword != null\r
+                        ? "clientCertPassword="\r
+                                + java.util.Base64.getEncoder().encodeToString(clientCertPassword.getBytes()) + ", "\r
+                        : "")\r
+                + (truststoreFilename != null ? "truststoreFilename=" + truststoreFilename + ", " : "")\r
+                + "connectTimeoutInMs=" + connectTimeoutInMs + ", readTimeoutInMs=" + readTimeoutInMs + ", "\r
+                + (authenticationMode != null ? "authenticationMode=" + authenticationMode + ", " : "")\r
+                + (basicAuthUsername != null ? "basicAuthUsername=" + basicAuthUsername + ", " : "")\r
+                + (basicAuthPassword != null ? "basicAuthPassword="\r
+                        + java.util.Base64.getEncoder().encodeToString(basicAuthPassword.getBytes()) : "")\r
+                + "]";\r
+    }\r
 \r
 }\r