This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 79dbd01  GEODE-6450: ClientClusterManagementService supports ssl 
connection (#3276)
79dbd01 is described below

commit 79dbd01d57ae7e9df32976aa993394bf5767df03
Author: jinmeiliao <[email protected]>
AuthorDate: Fri Mar 8 12:53:11 2019 -0800

    GEODE-6450: ClientClusterManagementService supports ssl connection (#3276)
    
    Co-authored-by: Jens Deppe <[email protected]>
    
    * provide capability for the client to configure ssl connection when 
getting the cluster management service.
    * from the server side, create the SSLContext from the ssl configuration 
specified on the server
    * refactor ssl code
---
 ...tandaloneClientManagementAPIAcceptanceTest.java |   2 +
 .../resources/ManagementClientCreateRegion.java    |   2 +-
 .../rest/ClientClusterManagementSSLTest.java       | 182 +++++++++++++++++++++
 .../ClientClusterManagementServiceDunitTest.java   |   3 +-
 .../integrationTest/resources/assembly_content.txt |   2 +
 .../resources/dependency_classpath.txt             |   2 +
 .../integrationTest/resources/expected_jars.txt    |   2 +
 ...ClusterManagementServiceRetrievalDUnitTest.java |   3 +-
 .../apache/geode/internal/cache/HttpService.java   |  35 +---
 .../apache/geode/management/internal/SSLUtil.java  | 114 +++++++++++--
 .../api/GeodeClusterManagementServiceFactory.java  |  74 ++++++---
 .../internal/cli/commands/ConnectCommand.java      |  83 +---------
 .../internal/cli/domain/MemberInformation.java     |   9 +
 .../functions/GetMemberInformationFunction.java    |   7 +
 .../sanctioned-geode-core-serializables.txt        |   2 +-
 geode-management/build.gradle                      |   2 +
 .../geode/cache/configuration/RegionConfig.java    |   2 +-
 .../management/api/ClusterManagementService.java   |  12 ++
 .../geode/management/api/RestfulEndpoint.java      |   5 +
 .../client/ClusterManagementServiceProvider.java   |  77 +++++----
 .../internal/ClientClusterManagementService.java   |  56 +++++--
 .../internal/ClusterManagementServiceFactory.java  |  34 ++--
 .../JavaClientClusterManagementServiceFactory.java |  28 ++--
 .../src/test/resources/expected-pom.xml            |   5 +
 .../rest/security/RestSecurityConfiguration.java   |   2 +-
 25 files changed, 508 insertions(+), 237 deletions(-)

diff --git 
a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/StandaloneClientManagementAPIAcceptanceTest.java
 
b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/StandaloneClientManagementAPIAcceptanceTest.java
index b0187dd..f2210e6 100644
--- 
a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/StandaloneClientManagementAPIAcceptanceTest.java
+++ 
b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/StandaloneClientManagementAPIAcceptanceTest.java
@@ -87,6 +87,8 @@ public class StandaloneClientManagementAPIAcceptanceTest {
         "jackson-annotations",
         "jackson-core",
         "jackson-databind",
+        "httpclient",
+        "httpcore",
         "spring-beans",
         "spring-core",
         "spring-web")) {
diff --git 
a/geode-assembly/src/acceptanceTest/resources/ManagementClientCreateRegion.java 
b/geode-assembly/src/acceptanceTest/resources/ManagementClientCreateRegion.java
index df612f9..2ed8e9b 100644
--- 
a/geode-assembly/src/acceptanceTest/resources/ManagementClientCreateRegion.java
+++ 
b/geode-assembly/src/acceptanceTest/resources/ManagementClientCreateRegion.java
@@ -23,7 +23,7 @@ public class ManagementClientTestCreateRegion {
     String regionName = args[0];
 
     ClusterManagementService cms =
-        
ClusterManagementServiceProvider.getService("http://localhost:7070/geode-management";);
+        ClusterManagementServiceProvider.getService("localhost", 7070);
 
     RegionConfig config = new RegionConfig();
     config.setName(regionName);
diff --git 
a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
 
b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
new file mode 100644
index 0000000..6ef47cf
--- /dev/null
+++ 
b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.geode.management.internal.rest;
+
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.File;
+import java.util.Properties;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.springframework.web.client.ResourceAccessException;
+
+import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.examples.SimpleSecurityManager;
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.api.ClusterManagementService;
+import org.apache.geode.management.client.ClusterManagementServiceProvider;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+
+public class ClientClusterManagementSSLTest {
+
+  @ClassRule
+  public static ClusterStartupRule cluster = new ClusterStartupRule(2);
+
+  private static MemberVM locator, server;
+  private ClusterManagementService cmsClient;
+  private RegionConfig region;
+  private static SSLContext sslContext;
+  private static HostnameVerifier hostnameVerifier;
+
+  @ClassRule
+  public static RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    File keyFile = new 
File(ClientClusterManagementSSLTest.class.getClassLoader()
+        .getResource("ssl/trusted.keystore").getFile());
+    Properties sslProps = new Properties();
+    sslProps.setProperty(SSL_KEYSTORE, keyFile.getCanonicalPath());
+    sslProps.setProperty(SSL_TRUSTSTORE, keyFile.getCanonicalPath());
+    sslProps.setProperty(SSL_KEYSTORE_PASSWORD, "password");
+    sslProps.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
+    sslProps.setProperty(SSL_ENABLED_COMPONENTS, 
SecurableCommunicationChannel.WEB.getConstant());
+    locator = cluster.startLocatorVM(0, l -> 
l.withHttpService().withProperties(sslProps)
+        .withSecurityManager(SimpleSecurityManager.class));
+    int locatorPort = locator.getPort();
+    server = cluster.startServerVM(1, s -> 
s.withConnectionToLocator(locatorPort)
+        .withProperties(sslProps)
+        .withCredential("cluster", "cluster"));
+
+    System.setProperty("javax.net.ssl.keyStore", keyFile.getCanonicalPath());
+    System.setProperty("javax.net.ssl.keyStorePassword", "password");
+    System.setProperty("javax.net.ssl.keyStoreType", "JKS");
+    System.setProperty("javax.net.ssl.trustStore", keyFile.getCanonicalPath());
+    System.setProperty("javax.net.ssl.trustStorePassword", "password");
+    System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+
+    sslContext = SSLContext.getDefault();
+    hostnameVerifier = new NoopHostnameVerifier();
+  }
+
+  @Before
+  public void before() throws Exception {
+    region = new RegionConfig();
+    region.setName("customer");
+  }
+
+  @Test
+  public void createRegion_Successful() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        sslContext, hostnameVerifier, "dataManage", "dataManage");
+
+    ClusterManagementResult result = cmsClient.create(region);
+    assertThat(result.isSuccessful()).isTrue();
+    
assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.OK);
+    assertThat(result.getMemberStatuses()).containsKeys("server-1").hasSize(1);
+  }
+
+  @Test
+  public void createRegion_NoSsl() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        null, null, "dataManage", "dataManage");
+    assertThatThrownBy(() -> 
cmsClient.create(region)).isInstanceOf(ResourceAccessException.class);
+  }
+
+  @Test
+  public void createRegion_WrongPassword() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        sslContext, hostnameVerifier, "dataManage", "wrongPswd");
+
+    ClusterManagementResult result = cmsClient.create(region);
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.getStatusCode())
+        .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+  }
+
+  @Test
+  public void createRegion_NoUser() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        sslContext, hostnameVerifier, null, null);
+
+    ClusterManagementResult result = cmsClient.create(region);
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.getStatusCode())
+        .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+  }
+
+  @Test
+  public void createRegion_NoPassword() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        sslContext, hostnameVerifier, "dataManage", null);
+
+    ClusterManagementResult result = cmsClient.create(region);
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.getStatusCode())
+        .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+  }
+
+  @Test
+  public void createRegion_NoPrivilege() throws Exception {
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort(),
+        sslContext, hostnameVerifier, "dataRead", "dataRead");
+
+    ClusterManagementResult result = cmsClient.create(region);
+    assertThat(result.isSuccessful()).isFalse();
+    
assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.UNAUTHORIZED);
+  }
+
+  @Test
+  public void invokeFromServer() throws Exception {
+    server.invoke(() -> {
+      // when getting the service from the server, we don't need to provide 
the host information
+      ClusterManagementService cmsClient =
+          ClusterManagementServiceProvider.getService("dataManage", 
"dataManage");
+      RegionConfig region = new RegionConfig();
+      region.setName("orders");
+      cmsClient.create(region);
+
+      // verify that the region is created on the server
+      
assertThat(ClusterStartupRule.getCache().getRegion("/orders")).isNotNull();
+    });
+
+    // verify that the configuration is persisted on the locator
+    locator.invoke(() -> {
+      CacheConfig cacheConfig =
+          ClusterStartupRule.getLocator().getConfigurationPersistenceService()
+              .getCacheConfig("cluster");
+      assertThat(CacheElement.findElement(cacheConfig.getRegions(), 
"orders")).isNotNull();
+    });
+  }
+}
diff --git 
a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
 
b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
index 2063b15..e09e65a 100644
--- 
a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
+++ 
b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
@@ -39,8 +39,7 @@ public class ClientClusterManagementServiceDunitTest {
   public static void beforeClass() {
     locator = cluster.startLocatorVM(0, l -> l.withHttpService());
     server = cluster.startServerVM(1, locator.getPort());
-    cmsClient = ClusterManagementServiceProvider
-        .getService("http://localhost:"; + locator.getHttpPort() + 
"/geode-management");
+    cmsClient = ClusterManagementServiceProvider.getService("localhost", 
locator.getHttpPort());
   }
 
   @Test
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt 
b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 6e2a71f..abca10f 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -908,6 +908,8 @@ lib/geode-wan-0.0.0.jar
 lib/geode-web-0.0.0.jar
 lib/gfsh-dependencies.jar
 lib/grumpy-core-0.2.2.jar
+lib/httpclient-4.5.6.jar
+lib/httpcore-4.4.10.jar
 lib/istack-commons-runtime-2.2.jar
 lib/jackson-annotations-2.9.8.jar
 lib/jackson-core-2.9.8.jar
diff --git 
a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt 
b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index ff5c134..e488c40 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -25,6 +25,8 @@ geode-protobuf-messages-0.0.0.jar
 geode-rebalancer-0.0.0.jar
 geode-wan-0.0.0.jar
 grumpy-core-0.2.2.jar
+httpclient-4.5.6.jar
+httpcore-4.4.10.jar
 istack-commons-runtime-2.2.jar
 jackson-annotations-2.9.8.jar
 jackson-core-2.9.8.jar
diff --git a/geode-assembly/src/integrationTest/resources/expected_jars.txt 
b/geode-assembly/src/integrationTest/resources/expected_jars.txt
index 2f5ae83..1b3e988 100644
--- a/geode-assembly/src/integrationTest/resources/expected_jars.txt
+++ b/geode-assembly/src/integrationTest/resources/expected_jars.txt
@@ -25,6 +25,8 @@ geo
 gfsh-dependencies.jar
 grumpy-core
 guava
+httpclient
+httpcore
 istack-commons-runtime
 j2objc-annotations
 jackson-annotations
diff --git 
a/geode-core/src/distributedTest/java/org/apache/geode/management/api/ClusterManagementServiceRetrievalDUnitTest.java
 
b/geode-core/src/distributedTest/java/org/apache/geode/management/api/ClusterManagementServiceRetrievalDUnitTest.java
index c83d9c6..f34f857 100644
--- 
a/geode-core/src/distributedTest/java/org/apache/geode/management/api/ClusterManagementServiceRetrievalDUnitTest.java
+++ 
b/geode-core/src/distributedTest/java/org/apache/geode/management/api/ClusterManagementServiceRetrievalDUnitTest.java
@@ -40,7 +40,8 @@ public class ClusterManagementServiceRetrievalDUnitTest {
         x -> x.withHttpService());
     server1 = cluster.startServerVM(1, locator.getPort());
 
-    final String url = String.format("http://localhost:%d";, 
locator.getHttpPort());
+    final String url =
+        String.format("http://localhost:%d/geode-management/v2";, 
locator.getHttpPort());
     server1.invoke(() -> {
       ClientClusterManagementService cms =
           (ClientClusterManagementService) 
ClusterManagementServiceProvider.getService();
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/HttpService.java 
b/geode-core/src/main/java/org/apache/geode/internal/cache/HttpService.java
index e7b0bcf..53c0e8a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/HttpService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/HttpService.java
@@ -36,7 +36,6 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.webapp.WebAppContext;
 
-import org.apache.geode.GemFireConfigException;
 import org.apache.geode.internal.admin.SSLConfig;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.internal.SSLUtil;
@@ -95,39 +94,7 @@ public class HttpService {
         
sslContextFactory.setIncludeCipherSuites(SSLUtil.readArray(sslConfig.getCiphers()));
       }
 
-      String protocol = 
SSLUtil.getSSLAlgo(SSLUtil.readArray(sslConfig.getProtocols()));
-      if (protocol != null) {
-        sslContextFactory.setProtocol(protocol);
-      } else {
-        logger.warn("SSL Protocol could not be determined. SSL settings might 
not work correctly");
-      }
-
-      if (StringUtils.isBlank(sslConfig.getKeystore())) {
-        throw new GemFireConfigException(
-            "Key store can't be empty if SSL is enabled for HttpService");
-      }
-
-      sslContextFactory.setKeyStorePath(sslConfig.getKeystore());
-
-      if (StringUtils.isNotBlank(sslConfig.getKeystoreType())) {
-        sslContextFactory.setKeyStoreType(sslConfig.getKeystoreType());
-      }
-
-      if (StringUtils.isNotBlank(sslConfig.getKeystorePassword())) {
-        sslContextFactory.setKeyStorePassword(sslConfig.getKeystorePassword());
-      }
-
-      if (StringUtils.isNotBlank(sslConfig.getTruststore())) {
-        sslContextFactory.setTrustStorePath(sslConfig.getTruststore());
-      }
-
-      if (StringUtils.isNotBlank(sslConfig.getTruststorePassword())) {
-        
sslContextFactory.setTrustStorePassword(sslConfig.getTruststorePassword());
-      }
-
-      if (StringUtils.isNotBlank(sslConfig.getTruststoreType())) {
-        sslContextFactory.setTrustStoreType(sslConfig.getTruststoreType());
-      }
+      
sslContextFactory.setSslContext(SSLUtil.createAndConfigureSSLContext(sslConfig, 
false));
 
       if (logger.isDebugEnabled()) {
         logger.debug(sslContextFactory.dump());
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/SSLUtil.java 
b/geode-core/src/main/java/org/apache/geode/management/internal/SSLUtil.java
index b974dff..931539c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/SSLUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/SSLUtil.java
@@ -14,27 +14,37 @@
  */
 package org.apache.geode.management.internal;
 
+import java.io.FileInputStream;
+import java.security.KeyStore;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Objects;
 
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
 
 import org.apache.commons.lang3.StringUtils;
 
+import org.apache.geode.internal.admin.SSLConfig;
+
 /**
  *
  * @since GemFire 8.1
  */
 public class SSLUtil {
-
-  public static String getSSLAlgo(String[] protocols) {
-    String c = null;
-
+  public static SSLContext getSSLContextInstance(SSLConfig sslConfig) {
+    String[] protocols = sslConfig.getProtocolsAsStringArray();
+    SSLContext sslContext = null;
     if (protocols != null && protocols.length > 0) {
       for (String protocol : protocols) {
         if (!protocol.equals("any")) {
           try {
-            SSLContext.getInstance(protocol);
-            c = protocol;
+            sslContext = SSLContext.getInstance(protocol);
             break;
           } catch (NoSuchAlgorithmException e) {
             // continue
@@ -42,21 +52,20 @@ public class SSLUtil {
         }
       }
     }
-    if (c != null) {
-      return c;
+    if (sslContext != null) {
+      return sslContext;
     }
     // lookup known algorithms
     String[] knownAlgorithms = {"SSL", "SSLv2", "SSLv3", "TLS", "TLSv1", 
"TLSv1.1", "TLSv1.2"};
     for (String algo : knownAlgorithms) {
       try {
-        SSLContext.getInstance(algo);
-        c = algo;
+        sslContext = SSLContext.getInstance(algo);
         break;
       } catch (NoSuchAlgorithmException e) {
         // continue
       }
     }
-    return c;
+    return sslContext;
   }
 
   /** Read an array of values from a string, whitespace or comma separated. */
@@ -68,4 +77,87 @@ public class SSLUtil {
     return text.split("[\\s,]+");
   }
 
+  public static SSLContext createAndConfigureSSLContext(SSLConfig sslConfig,
+      boolean skipSslVerification) {
+    try {
+      if (sslConfig.useDefaultSSLContext()) {
+        return SSLContext.getDefault();
+      }
+      SSLContext ssl = getSSLContextInstance(sslConfig);
+
+      KeyManager[] keyManagers = getKeyManagers(sslConfig);
+      TrustManager[] trustManagers = getTrustManagers(sslConfig, 
skipSslVerification);
+
+      ssl.init(keyManagers, trustManagers, new SecureRandom());
+      return ssl;
+    } catch (Exception e) {
+      throw new RuntimeException(e.getMessage(), e);
+    }
+  }
+
+  private static KeyManager[] getKeyManagers(SSLConfig sslConfig) throws 
Exception {
+    FileInputStream keyStoreStream = null;
+    KeyManagerFactory keyManagerFactory = null;
+
+    try {
+      if (StringUtils.isNotBlank(sslConfig.getKeystore())) {
+        String keyStoreType = Objects.toString(sslConfig.getKeystoreType(), 
"JKS");
+        KeyStore clientKeys = KeyStore.getInstance(keyStoreType);
+        keyStoreStream = new FileInputStream(sslConfig.getKeystore());
+        clientKeys.load(keyStoreStream, 
sslConfig.getKeystorePassword().toCharArray());
+
+        keyManagerFactory =
+            
KeyManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        keyManagerFactory.init(clientKeys, 
sslConfig.getKeystorePassword().toCharArray());
+      }
+    } finally {
+      if (keyStoreStream != null) {
+        keyStoreStream.close();
+      }
+    }
+
+    return keyManagerFactory != null ? keyManagerFactory.getKeyManagers() : 
null;
+  }
+
+  private static TrustManager[] getTrustManagers(SSLConfig sslConfig, boolean 
skipSslVerification)
+      throws Exception {
+    FileInputStream trustStoreStream = null;
+    TrustManagerFactory trustManagerFactory = null;
+
+    if (skipSslVerification) {
+      TrustManager[] trustAllCerts = new TrustManager[] {new 
X509TrustManager() {
+        @Override
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+          return null;
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] certs, String 
authType) {}
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] certs, String 
authType) {}
+
+      }};
+      return trustAllCerts;
+    }
+
+    try {
+      // load server public key
+      if (StringUtils.isNotBlank(sslConfig.getTruststore())) {
+        String trustStoreType = 
Objects.toString(sslConfig.getTruststoreType(), "JKS");
+        KeyStore serverPub = KeyStore.getInstance(trustStoreType);
+        trustStoreStream = new FileInputStream(sslConfig.getTruststore());
+        serverPub.load(trustStoreStream, 
sslConfig.getTruststorePassword().toCharArray());
+        trustManagerFactory =
+            
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        trustManagerFactory.init(serverPub);
+      }
+    } finally {
+      if (trustStoreStream != null) {
+        trustStoreStream.close();
+      }
+    }
+    return trustManagerFactory != null ? 
trustManagerFactory.getTrustManagers() : null;
+  }
+
 }
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeClusterManagementServiceFactory.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeClusterManagementServiceFactory.java
index d013e43..69fa458 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeClusterManagementServiceFactory.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeClusterManagementServiceFactory.java
@@ -18,7 +18,11 @@ package org.apache.geode.management.internal.api;
 import java.util.List;
 import java.util.Set;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.apache.commons.lang3.StringUtils;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.annotations.Immutable;
@@ -31,13 +35,16 @@ import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.distributed.internal.InternalLocator;
 import 
org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.internal.admin.SSLConfig;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.net.SSLConfigurationFactory;
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.apache.geode.management.api.ClusterManagementService;
 import org.apache.geode.management.client.ClusterManagementServiceProvider;
-import org.apache.geode.management.internal.ClientClusterManagementService;
 import org.apache.geode.management.internal.ClusterManagementServiceFactory;
 import 
org.apache.geode.management.internal.JavaClientClusterManagementServiceFactory;
+import org.apache.geode.management.internal.SSLUtil;
 import org.apache.geode.management.internal.cli.domain.MemberInformation;
 import 
org.apache.geode.management.internal.cli.functions.GetMemberInformationFunction;
 
@@ -47,8 +54,8 @@ import 
org.apache.geode.management.internal.cli.functions.GetMemberInformationFu
  * address of the {@code ClusterManagementService} when using the {@code 
create()} call. Otherwise
  * an explicit can also be used.
  */
-public class GeodeClusterManagementServiceFactory extends
-    JavaClientClusterManagementServiceFactory {
+public class GeodeClusterManagementServiceFactory
+    extends JavaClientClusterManagementServiceFactory {
 
   @Immutable
   private static final GetMemberInformationFunction 
MEMBER_INFORMATION_FUNCTION =
@@ -61,8 +68,12 @@ public class GeodeClusterManagementServiceFactory extends
     return ClusterManagementServiceProvider.GEODE_CONTEXT;
   }
 
+  public ClusterManagementService create() {
+    return create(null, null);
+  }
+
   @Override
-  public ClusterManagementService create() throws IllegalStateException {
+  public ClusterManagementService create(String username, String password) {
     if (InternalLocator.getLocator() != null) {
       return InternalLocator.getLocator().getClusterManagementService();
     }
@@ -74,45 +85,52 @@ public class GeodeClusterManagementServiceFactory extends
       Set<InternalDistributedMember> locatorsWithClusterConfig =
           
cacheImpl.getDistributionManager().getAllHostedLocatorsWithSharedConfiguration()
               .keySet();
-      String serviceAddress = getHttpServiceAddress(locatorsWithClusterConfig);
 
-      return new ClientClusterManagementService(serviceAddress);
+      MemberInformation memberInformation = 
getHttpServiceAddress(locatorsWithClusterConfig);
+
+      SSLContext sslContext = null;
+      HostnameVerifier hostnameVerifier = null;
+      if (memberInformation.isSsl()) {
+        SSLConfig sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(
+            ((GemFireCacheImpl) cache).getSystem().getConfig(), 
SecurableCommunicationChannel.WEB);
+        if (sslConfig.getTruststore() == null) {
+          throw new IllegalStateException(
+              "The server needs to have truststore specified in order to use 
cluster management service.");
+        }
+
+        sslContext = SSLUtil.createAndConfigureSSLContext(sslConfig, false);
+        hostnameVerifier = new NoopHostnameVerifier();
+      }
+
+      return create(getHostName(memberInformation), 
memberInformation.getHttpServicePort(),
+          sslContext, hostnameVerifier, username, password);
     }
 
     ClientCache clientCache = ClientCacheFactory.getAnyInstance();
     if (clientCache != null) {
       throw new IllegalStateException(
-          "Under construction. To retrieve an instance of 
ClusterManagementService from a Geode client, please use either 
create(clusterUrl) or create(requestFactory) methods");
+          "Under construction. To retrieve an instance of 
ClusterManagementService from a Geode client, please use other methods");
     }
     // } catch( CacheClosedException e) {
     throw new IllegalStateException("ClusterManagementService.create() " +
         "must be executed on one of locator, server or client cache VMs");
   }
 
-  private String getHttpServiceAddress(Set<InternalDistributedMember> 
locators) {
-    for (InternalDistributedMember locator : locators) {
 
+  private MemberInformation 
getHttpServiceAddress(Set<InternalDistributedMember> locators) {
+    for (InternalDistributedMember locator : locators) {
       try {
         ResultCollector resultCollector =
             
FunctionService.onMember(locator).execute(MEMBER_INFORMATION_FUNCTION);
-        List<MemberInformation> memberInformation =
+        List<MemberInformation> memberInformations =
             (List<MemberInformation>) resultCollector.getResult();
         // Is this even possible?
-        if (memberInformation.isEmpty()) {
+        if (memberInformations.isEmpty()) {
           continue;
         }
 
-        // What address to use
-        String host;
-        if 
(StringUtils.isNotBlank(memberInformation.get(0).getHttpServiceBindAddress())) {
-          host = memberInformation.get(0).getHttpServiceBindAddress();
-        } else if 
(StringUtils.isNotBlank(memberInformation.get(0).getServerBindAddress())) {
-          host = memberInformation.get(0).getServerBindAddress();
-        } else {
-          host = memberInformation.get(0).getHost();
-        }
-
-        return String.format("http://%s:%d";, host, 
memberInformation.get(0).getHttpServicePort());
+        // return the first available one. Later for HA, we can return the 
entire list
+        return memberInformations.get(0);
       } catch (FunctionException e) {
         logger.warn("Unable to execute GetMemberInformationFunction on " + 
locator.getId());
         throw new IllegalStateException(e);
@@ -121,4 +139,16 @@ public class GeodeClusterManagementServiceFactory extends
 
     throw new IllegalStateException("Unable to determine 
ClusterManagementService endpoint");
   }
+
+  private String getHostName(MemberInformation memberInformation) {
+    String host;
+    if (StringUtils.isNotBlank(memberInformation.getHttpServiceBindAddress())) 
{
+      host = memberInformation.getHttpServiceBindAddress();
+    } else if 
(StringUtils.isNotBlank(memberInformation.getServerBindAddress())) {
+      host = memberInformation.getServerBindAddress();
+    } else {
+      host = memberInformation.getHost();
+    }
+    return host;
+  }
 }
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
index 25d49d9..e8cfa3d 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
@@ -20,26 +20,17 @@ import static 
org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_
 import static 
org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_PREFIX;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.Properties;
 
 import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
 
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.shell.core.annotation.CliCommand;
@@ -429,83 +420,13 @@ public class ConnectCommand extends OfflineGfshCommand {
         locatorResponse.isJmxManagerSslEnabled());
   }
 
-  private KeyManager[] getKeyManagers(SSLConfig sslConfig) throws Exception {
-    FileInputStream keyStoreStream = null;
-    KeyManagerFactory keyManagerFactory = null;
 
-    try {
-      if (StringUtils.isNotBlank(sslConfig.getKeystore())) {
-        KeyStore clientKeys = 
KeyStore.getInstance(sslConfig.getKeystoreType());
-        keyStoreStream = new FileInputStream(sslConfig.getKeystore());
-        clientKeys.load(keyStoreStream, 
sslConfig.getKeystorePassword().toCharArray());
-
-        keyManagerFactory =
-            
KeyManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        keyManagerFactory.init(clientKeys, 
sslConfig.getKeystorePassword().toCharArray());
-      }
-    } finally {
-      if (keyStoreStream != null) {
-        keyStoreStream.close();
-      }
-    }
-
-    return keyManagerFactory != null ? keyManagerFactory.getKeyManagers() : 
null;
-  }
-
-  private TrustManager[] getTrustManagers(SSLConfig sslConfig, boolean 
skipSslVerification)
-      throws Exception {
-    FileInputStream trustStoreStream = null;
-    TrustManagerFactory trustManagerFactory = null;
-
-    if (skipSslVerification) {
-      TrustManager[] trustAllCerts = new TrustManager[] {new 
X509TrustManager() {
-        @Override
-        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-          return null;
-        }
-
-        @Override
-        public void checkClientTrusted(X509Certificate[] certs, String 
authType) {}
-
-        @Override
-        public void checkServerTrusted(X509Certificate[] certs, String 
authType) {}
-
-      }};
-      return trustAllCerts;
-    }
-
-    try {
-      // load server public key
-      if (StringUtils.isNotBlank(sslConfig.getTruststore())) {
-        KeyStore serverPub = 
KeyStore.getInstance(sslConfig.getTruststoreType());
-        trustStoreStream = new FileInputStream(sslConfig.getTruststore());
-        serverPub.load(trustStoreStream, 
sslConfig.getTruststorePassword().toCharArray());
-        trustManagerFactory =
-            
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        trustManagerFactory.init(serverPub);
-      }
-    } finally {
-      if (trustStoreStream != null) {
-        trustStoreStream.close();
-      }
-    }
-    return trustManagerFactory != null ? 
trustManagerFactory.getTrustManagers() : null;
-  }
-
-  private void configureHttpsURLConnection(SSLConfig sslConfig, boolean 
skipSslVerification)
-      throws Exception {
-    KeyManager[] keyManagers = getKeyManagers(sslConfig);
-    TrustManager[] trustManagers = getTrustManagers(sslConfig, 
skipSslVerification);
 
+  private void configureHttpsURLConnection(SSLConfig sslConfig, boolean 
skipSslVerification) {
+    SSLContext ssl = SSLUtil.createAndConfigureSSLContext(sslConfig, 
skipSslVerification);
     if (skipSslVerification) {
       HttpsURLConnection.setDefaultHostnameVerifier((String s, SSLSession 
sslSession) -> true);
     }
-
-    SSLContext ssl =
-        
SSLContext.getInstance(SSLUtil.getSSLAlgo(SSLUtil.readArray(sslConfig.getProtocols())));
-
-    ssl.init(keyManagers, trustManagers, new SecureRandom());
-
     HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());
   }
 
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/MemberInformation.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/MemberInformation.java
index 357b976..0d7b9ce 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/MemberInformation.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/MemberInformation.java
@@ -50,6 +50,7 @@ public class MemberInformation implements Serializable {
   private double cpuUsage;
   private Set<String> hostedRegions;
   private String offHeapMemorySize;
+  private boolean ssl;
 
   public String getName() {
     return name;
@@ -239,4 +240,12 @@ public class MemberInformation implements Serializable {
   public void setOffHeapMemorySize(String v) {
     this.offHeapMemorySize = v;
   }
+
+  public boolean isSsl() {
+    return ssl;
+  }
+
+  public void setSsl(boolean ssl) {
+    this.ssl = ssl;
+  }
 }
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetMemberInformationFunction.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetMemberInformationFunction.java
index 88c4ee4..0a248a4 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetMemberInformationFunction.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetMemberInformationFunction.java
@@ -28,11 +28,14 @@ import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.admin.SSLConfig;
 import org.apache.geode.internal.cache.CacheClientStatus;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.execute.InternalFunction;
 import org.apache.geode.internal.cache.tier.InternalClientMembership;
 import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.net.SSLConfigurationFactory;
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.domain.CacheServerInfo;
 import org.apache.geode.management.internal.cli.domain.MemberInformation;
@@ -87,6 +90,9 @@ public class GetMemberInformationFunction implements 
InternalFunction {
       memberInfo.setHost(member.getHost());
       memberInfo.setProcessId("" + member.getProcessId());
 
+      SSLConfig sslConfig = 
SSLConfigurationFactory.getSSLConfigForComponent(config,
+          SecurableCommunicationChannel.WEB);
+      memberInfo.setSsl(sslConfig.isEnabled());
       memberInfo.setGroups(config.getGroups());
       memberInfo.setLogFilePath(config.getLogFile().getCanonicalPath());
       
memberInfo.setStatArchiveFilePath(config.getStatisticArchiveFile().getCanonicalPath());
@@ -96,6 +102,7 @@ public class GetMemberInformationFunction implements 
InternalFunction {
       memberInfo.setServerBindAddress(config.getServerBindAddress());
       memberInfo.setOffHeapMemorySize(config.getOffHeapMemorySize());
       memberInfo.setHttpServicePort(config.getHttpServicePort());
+
       memberInfo.setHttpServiceBindAddress(config.getHttpServiceBindAddress());
 
       MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
diff --git 
a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
 
b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index 4d46693..de29bf1 100644
--- 
a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ 
b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -525,7 +525,7 @@ 
org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo,tru
 
org/apache/geode/management/internal/cli/domain/IndexDetails,true,-2198907141534201288,fromClause:java/lang/String,indexName:java/lang/String,indexStatisticsDetails:org/apache/geode/management/internal/cli/domain/IndexDetails$IndexStatisticsDetails,indexType:org/apache/geode/cache/query/IndexType,indexedExpression:java/lang/String,isValid:boolean,memberId:java/lang/String,memberName:java/lang/String,projectionAttributes:java/lang/String,regionName:java/lang/String,regionPath:java/lang/String
 
org/apache/geode/management/internal/cli/domain/IndexDetails$IndexStatisticsDetails,false,numberOfKeys:java/lang/Long,numberOfUpdates:java/lang/Long,numberOfValues:java/lang/Long,totalUpdateTime:java/lang/Long,totalUses:java/lang/Long
 
org/apache/geode/management/internal/cli/domain/MemberConfigurationInfo,false,cacheAttributes:java/util/Map,cacheServerAttributes:java/util/List,gfePropsRuntime:java/util/Map,gfePropsSetFromFile:java/util/Map,gfePropsSetUsingApi:java/util/Map,gfePropsSetWithDefaults:java/util/Map,jvmInputArguments:java/util/List,pdxAttributes:java/util/Map,systemProperties:java/util/Properties
-org/apache/geode/management/internal/cli/domain/MemberInformation,true,1,cacheServerList:java/util/List,cacheXmlFilePath:java/lang/String,clientCount:int,cpuUsage:double,groups:java/lang/String,heapUsage:java/lang/String,host:java/lang/String,hostedRegions:java/util/Set,httpServiceBindAddress:java/lang/String,httpServicePort:int,id:java/lang/String,initHeapSize:java/lang/String,isServer:boolean,locatorPort:int,locators:java/lang/String,logFilePath:java/lang/String,maxHeapSize:java/lang/S
 [...]
+org/apache/geode/management/internal/cli/domain/MemberInformation,true,1,cacheServerList:java/util/List,cacheXmlFilePath:java/lang/String,clientCount:int,cpuUsage:double,groups:java/lang/String,heapUsage:java/lang/String,host:java/lang/String,hostedRegions:java/util/Set,httpServiceBindAddress:java/lang/String,httpServicePort:int,id:java/lang/String,initHeapSize:java/lang/String,isServer:boolean,locatorPort:int,locators:java/lang/String,logFilePath:java/lang/String,maxHeapSize:java/lang/S
 [...]
 
org/apache/geode/management/internal/cli/domain/PartitionAttributesInfo,true,1,colocatedWith:java/lang/String,fpaInfoList:java/util/List,localMaxMemory:int,nonDefaultAttributes:java/util/Map,partitionResolverName:java/lang/String,recoveryDelay:long,redundantCopies:int,startupRecoveryDelay:long,totalNumBuckets:int
 
org/apache/geode/management/internal/cli/domain/RegionAttributesInfo,true,336184564012988487,asyncEventQueueIDs:java/util/Set,cacheListenerClassNames:java/util/List,cacheLoaderClassName:java/lang/String,cacheWriterClassName:java/lang/String,cloningEnabled:boolean,compressorClassName:java/lang/String,concurrencyChecksEnabled:boolean,concurrencyLevel:int,customExpiryIdleTimeoutClass:java/lang/String,customExpiryTTLClass:java/lang/String,dataPolicy:org/apache/geode/cache/DataPolicy,diskStor
 [...]
 
org/apache/geode/management/internal/cli/domain/RegionDescription,true,6461449275798378332,cndEvictionAttributes:java/util/Map,cndPartitionAttributes:java/util/Map,cndRegionAttributes:java/util/Map,dataPolicy:org/apache/geode/cache/DataPolicy,isAccessor:boolean,isLocal:boolean,isPartition:boolean,isPersistent:boolean,isReplicate:boolean,name:java/lang/String,regionDescPerMemberMap:java/util/Map,scope:org/apache/geode/cache/Scope
diff --git a/geode-management/build.gradle b/geode-management/build.gradle
index 091f79c..a30d1df 100755
--- a/geode-management/build.gradle
+++ b/geode-management/build.gradle
@@ -25,6 +25,8 @@ dependencies {
   compile('com.fasterxml.jackson.core:jackson-annotations')
   compile('org.springframework:spring-web')
   compile('javax.xml.bind:jaxb-api')
+  compile('javax.xml.bind:jaxb-api')
+    compile('org.apache.httpcomponents:httpclient')
 
   compileOnly(project(':geode-common')) {
     exclude module: 'junit'
diff --git 
a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
 
b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
index 45a063a..eae46ba 100644
--- 
a/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
+++ 
b/geode-management/src/main/java/org/apache/geode/cache/configuration/RegionConfig.java
@@ -175,7 +175,7 @@ public class RegionConfig implements CacheElement, 
RestfulEndpoint {
 
   @Override
   public String getEndpoint() {
-    return "/v2/regions";
+    return "/regions";
   }
 
   public RegionAttributesType getRegionAttributes() {
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
 
b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
index 2b33cea..658906e 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
@@ -36,6 +36,10 @@ public interface ClusterManagementService {
    */
   ClusterManagementResult create(CacheElement config, String group);
 
+  default ClusterManagementResult create(CacheElement config) {
+    return create(config, null);
+  }
+
   /**
    * This method will delete the element on all the applicable members in the 
cluster and update the
    * configuration in the cluster configuration if persistence is enabled.
@@ -48,6 +52,10 @@ public interface ClusterManagementService {
    */
   ClusterManagementResult delete(CacheElement config, String group);
 
+  default ClusterManagementResult delete(CacheElement config) {
+    return delete(config, null);
+  }
+
   /**
    * This method will update the element on all the applicable members in the 
cluster and persist
    * the updated configuration in the cluster configuration if persistence is 
enabled.
@@ -60,4 +68,8 @@ public interface ClusterManagementService {
    */
   ClusterManagementResult update(CacheElement config, String group);
 
+  default ClusterManagementResult update(CacheElement config) {
+    return update(config, null);
+  }
+
 }
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/api/RestfulEndpoint.java
 
b/geode-management/src/main/java/org/apache/geode/management/api/RestfulEndpoint.java
index 81736df..591c399 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/api/RestfulEndpoint.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/api/RestfulEndpoint.java
@@ -17,5 +17,10 @@ package org.apache.geode.management.api;
 
 public interface RestfulEndpoint {
 
+  /**
+   * this needs to return the uri portion after the /geode-management/v2
+   *
+   * @return e.g. /regions
+   */
   String getEndpoint();
 }
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/client/ClusterManagementServiceProvider.java
 
b/geode-management/src/main/java/org/apache/geode/management/client/ClusterManagementServiceProvider.java
index a1fc1ce..ec2703a 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/client/ClusterManagementServiceProvider.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/client/ClusterManagementServiceProvider.java
@@ -19,6 +19,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.ServiceLoader;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.springframework.http.client.ClientHttpRequestFactory;
 
 import org.apache.geode.annotations.Experimental;
@@ -67,64 +70,58 @@ public class ClusterManagementServiceProvider {
   private static Map<String, ClusterManagementServiceFactory> serviceFactories 
= null;
 
   /**
-   * Without any options, this method will try to retrieve the correct
-   * {@code ClusterManagementService} dependent on the context in which it is 
called - relevant
-   * contexts are locators, servers and geode clients (essentially wherever a 
{@code Cache} or
-   * {@code ClientCache} exist).
-   *
-   * @return a {@code ClusterManagementService} instance configured to connect 
to the service
-   *         endpoint.
-   * @throws IllegalArgumentException if the service instance cannot be 
retrieved, for example if
-   *         not called from a suitable context.
+   * use this to get the ClusterManagementService from the locator, or from a 
server that connects
+   * to a locator with no security manager.
    */
   public static ClusterManagementService getService() {
     return getServiceFactory(GEODE_CONTEXT).create();
   }
 
   /**
+   * use this retrieve a ClusterManagementService from a server that connects 
to a secured locator
+   */
+  public static ClusterManagementService getService(String username, String 
password) {
+    return getServiceFactory(GEODE_CONTEXT).create(username, password);
+  }
+
+  /**
    * Retrieve a {@code ClusterManagementService} instance configured with an 
explicit service
-   * endpoint.
+   * endpoint. this is good for end point with no ssl nor security turned on.
    * <p/>
    * For example:
    *
    * <pre>
-   * 
ClusterManagementServiceProvider.getService("http://locator-host:7070/geode-management";)
+   * ClusterManagementServiceProvider.getService("locatorHost", "7070")
    * </pre>
    *
-   * @param clusterUrl the URL of the Cluster Management Service running on a 
locator. The port
-   *        used is as configured by the <i>http-service-port</i> property on 
the Geode locator.
-   * @return a {@code ClusterManagementService} instance configured to connect 
to the service
-   *         endpoint.
    * @throws IllegalArgumentException if the provided url is malformed
    */
-  public static ClusterManagementService getService(String clusterUrl) {
-    return getServiceFactory(JAVA_CLIENT_CONTEXT).create(clusterUrl);
+  public static ClusterManagementService getService(String host, int port) {
+    return getServiceFactory(JAVA_CLIENT_CONTEXT).create(host, port, null, 
null, null, null);
   }
 
   /**
-   * Retrieve a {@code ClusterManagementService} instance configured with a
-   * {@link ClientHttpRequestFactory}. This would be required when connecting 
to a SSL enabled
-   * endpoint.
-   * <p/>
-   * For example:
-   *
-   * <pre>
-   *   String clusterUrl = "https://locator-host:7070/geode-management";;
-   *
-   *   HttpComponentsClientHttpRequestFactory requestFactory = new 
HttpComponentsClientHttpRequestFactory();
-   *   DefaultHttpClient httpClient = (DefaultHttpClient) 
requestFactory.getHttpClient();
-   *   TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
-   *   SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, 
ALLOW_ALL_HOSTNAME_VERIFIER);
-   *   httpClient.getConnectionManager().getSchemeRegistry().register(new 
Scheme("https", 7070, sf));
-   *
-   *   RestTemplate restTemplate = new RestTemplate(requestFactory);
-   *
-   *   DefaultUriTemplateHandler templateHandler = new 
DefaultUriTemplateHandler();
-   *   templateHandler.setBaseUrl(clusterUrl);
-   *   restTemplate.setUriTemplateHandler(templateHandler);
+   * Retrieve a {@code ClusterManagementService} instance configured with an 
explicit service
+   * endpoint. This service will allow you to connect to ssl enabled and 
security enabled end point
+   * with the specified sslContext and hostnameVerifier
    *
-   *   ClusterManagementServiceProvider.getService(restTemplate);
-   * </pre>
+   * @param host the locator's host name
+   * @param port http port of the locator
+   * @param sslContext a pre configured sslContext to connect with
+   * @param hostnameVerifier a pre configured hostnameVerifier to connect with
+   * @param username if cluster has security manager, use this username to 
connect
+   * @param password if cluster has security manager, use this password to 
connect
+   */
+  public static ClusterManagementService getService(String host, int port, 
SSLContext sslContext,
+      HostnameVerifier hostnameVerifier, String username, String password) {
+    return getServiceFactory(JAVA_CLIENT_CONTEXT).create(host, port, 
sslContext, hostnameVerifier,
+        username, password);
+  }
+
+  /**
+   * Retrieve a {@code ClusterManagementService} instance configured with a
+   * {@link ClientHttpRequestFactory} with a general requestFactory. you can 
configure the
+   * requestFactory to tailor to your need to connect to the end point.
    *
    * @param requestFactory the Request Factory configured with the URL of the 
Cluster Management
    *        Service running on a locator. The port used is as configured by the
@@ -155,4 +152,6 @@ public class ClusterManagementServiceProvider {
       serviceFactories.put(factory.getContext(), factory);
     }
   }
+
+
 }
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
 
b/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
index 1ac48a0..840fd99 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
@@ -15,8 +15,19 @@
 
 package org.apache.geode.management.internal;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.apache.commons.lang3.NotImplementedException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.web.client.ResponseErrorHandler;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.util.DefaultUriTemplateHandler;
@@ -54,34 +65,58 @@ public class ClientClusterManagementService implements 
ClusterManagementService
     restTemplate.setErrorHandler(DEFAULT_ERROR_HANDLER);
   }
 
-  public ClientClusterManagementService(ClientHttpRequestFactory 
requestFactory) {
+  public ClientClusterManagementService(String host, int port, SSLContext 
sslContext,
+      HostnameVerifier hostnameVerifier, String username, String password) {
     this();
-    this.restTemplate.setRequestFactory(requestFactory);
-  }
 
-  public ClientClusterManagementService(String clusterUrl) {
-    this();
     DefaultUriTemplateHandler templateHandler = new 
DefaultUriTemplateHandler();
-    templateHandler.setBaseUrl(clusterUrl);
+    String schema = (sslContext == null) ? "http" : "https";
+    templateHandler.setBaseUrl(schema + "://" + host + ":" + port + 
"/geode-management/v2");
     restTemplate.setUriTemplateHandler(templateHandler);
+
+    // HttpComponentsClientHttpRequestFactory allows use to preconfigure 
httpClient for
+    // authentication and ssl context
+    HttpComponentsClientHttpRequestFactory requestFactory =
+        new HttpComponentsClientHttpRequestFactory();
+
+    HttpClientBuilder clientBuilder = HttpClientBuilder.create();
+    // configures the clientBuilder
+    if (username != null) {
+      CredentialsProvider credsProvider = new BasicCredentialsProvider();
+      credsProvider.setCredentials(new AuthScope(host, port),
+          new UsernamePasswordCredentials(username, password));
+      clientBuilder.setDefaultCredentialsProvider(credsProvider);
+    }
+
+    clientBuilder.setSSLContext(sslContext);
+    clientBuilder.setSSLHostnameVerifier(hostnameVerifier);
+
+    requestFactory.setHttpClient(clientBuilder.build());
+    restTemplate.setRequestFactory(requestFactory);
+  }
+
+  public ClientClusterManagementService(ClientHttpRequestFactory 
requestFactory) {
+    this();
+    this.restTemplate.setRequestFactory(requestFactory);
   }
 
   @Override
   public ClusterManagementResult create(CacheElement config, String group) {
     String endPoint = getEndpoint(config);
-
+    HttpHeaders headers = new HttpHeaders();
+    headers.setContentType(MediaType.APPLICATION_JSON);
     // the response status code info is represented by the 
ClusterManagementResult.errorCode already
-    return restTemplate.postForEntity(endPoint, config, 
ClusterManagementResult.class).getBody();
+    return restTemplate.postForObject(endPoint, config, 
ClusterManagementResult.class);
   }
 
   @Override
   public ClusterManagementResult delete(CacheElement config, String group) {
-    throw new NotImplementedException("Not implemented");
+    throw new NotImplementedException("Not Implemented");
   }
 
   @Override
   public ClusterManagementResult update(CacheElement config, String group) {
-    throw new NotImplementedException("Not implemented");
+    throw new NotImplementedException("Not Implemented");
   }
 
   public RestTemplate getRestTemplate() {
@@ -97,4 +132,5 @@ public class ClientClusterManagementService implements 
ClusterManagementService
 
     return ((RestfulEndpoint) config).getEndpoint();
   }
+
 }
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/internal/ClusterManagementServiceFactory.java
 
b/geode-management/src/main/java/org/apache/geode/management/internal/ClusterManagementServiceFactory.java
index 4489905..814e8a2 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/internal/ClusterManagementServiceFactory.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/internal/ClusterManagementServiceFactory.java
@@ -15,6 +15,9 @@
 
 package org.apache.geode.management.internal;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.springframework.http.client.ClientHttpRequestFactory;
 
 import org.apache.geode.management.api.ClusterManagementService;
@@ -30,29 +33,14 @@ public interface ClusterManagementServiceFactory {
    */
   String getContext();
 
-  /**
-   * Create a {@code ClusterManagementService} instance. Throws an {@code 
IllegalStateException}
-   * if the instance cannot be created. This method would typically be used by 
an implementation
-   * that is able to infer the correct Cluster Management endpoint URL to use.
-   *
-   * @return an instance of the {@code ClusterManagementService}
-   */
-  ClusterManagementService create() throws IllegalStateException;
-
-  /**
-   * Create a {@code ClusterManagementService} that will use the given URL.
-   *
-   * @param clusterUrl the URL to conect to
-   * @return an instance of {@code ClusterManagementService}
-   */
-  ClusterManagementService create(String clusterUrl);
+  // plain java client side
+  ClusterManagementService create(String host, int port, SSLContext sslContext,
+      HostnameVerifier hostnameVerifier, String username, String password);
 
-  /**
-   * Create a {@code ClusterManagementService} that will use the given {@link
-   * ClientHttpRequestFactory} to establish connections with the Cluster 
Management endpoint.
-   *
-   * @param requestFactory the {@code ClientHttpRequestFactory} to use for new 
connections.
-   * @return an instance of {@code ClusterManagementService}
-   */
   ClusterManagementService create(ClientHttpRequestFactory requestFactory);
+
+  // geode server side, we can infer host and port and useSSL properties from 
the server side
+  ClusterManagementService create();
+
+  ClusterManagementService create(String username, String password);
 }
diff --git 
a/geode-management/src/main/java/org/apache/geode/management/internal/JavaClientClusterManagementServiceFactory.java
 
b/geode-management/src/main/java/org/apache/geode/management/internal/JavaClientClusterManagementServiceFactory.java
index 9acbd7c..0049f48 100644
--- 
a/geode-management/src/main/java/org/apache/geode/management/internal/JavaClientClusterManagementServiceFactory.java
+++ 
b/geode-management/src/main/java/org/apache/geode/management/internal/JavaClientClusterManagementServiceFactory.java
@@ -15,6 +15,9 @@
 
 package org.apache.geode.management.internal;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.springframework.http.client.ClientHttpRequestFactory;
 
 import org.apache.geode.management.api.ClusterManagementService;
@@ -26,8 +29,7 @@ import 
org.apache.geode.management.client.ClusterManagementServiceProvider;
  * inferred from the implied runtime context but needs to be specifically 
configured using a given
  * URL or {@code ClientHttpRequestFactory}.
  */
-public class JavaClientClusterManagementServiceFactory
-    implements ClusterManagementServiceFactory {
+public class JavaClientClusterManagementServiceFactory implements 
ClusterManagementServiceFactory {
 
   @Override
   public String getContext() {
@@ -35,19 +37,25 @@ public class JavaClientClusterManagementServiceFactory
   }
 
   @Override
-  public ClusterManagementService create() throws IllegalArgumentException {
-    throw new IllegalArgumentException(String.format(
-        "When using a %s context, you must call create(String) or 
create(ClientHttpRequestFactory)",
-        ClusterManagementServiceProvider.JAVA_CLIENT_CONTEXT));
+  public ClusterManagementService create(String host, int port, SSLContext 
sslContext,
+      HostnameVerifier hostnameVerifier, String username,
+      String password) {
+    return new ClientClusterManagementService(host, port, sslContext, 
hostnameVerifier, username,
+        password);
   }
 
   @Override
-  public ClusterManagementService create(String clusterUrl) {
-    return new ClientClusterManagementService(clusterUrl);
+  public ClusterManagementService create(ClientHttpRequestFactory 
requestFactory) {
+    return new ClientClusterManagementService(requestFactory);
   }
 
   @Override
-  public ClusterManagementService create(ClientHttpRequestFactory 
requestFactory) {
-    return new ClientClusterManagementService(requestFactory);
+  public ClusterManagementService create() {
+    throw new IllegalArgumentException("must be invoked with a host and port");
+  }
+
+  @Override
+  public ClusterManagementService create(String username, String password) {
+    throw new IllegalArgumentException("must be invoked with a host and port");
   }
 }
diff --git a/geode-management/src/test/resources/expected-pom.xml 
b/geode-management/src/test/resources/expected-pom.xml
index 48766c6..3437c02 100644
--- a/geode-management/src/test/resources/expected-pom.xml
+++ b/geode-management/src/test/resources/expected-pom.xml
@@ -76,5 +76,10 @@
       <artifactId>jaxb-api</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+      <scope>compile</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git 
a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
 
b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
index a7b1f53..ddcc1c8 100644
--- 
a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
+++ 
b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
@@ -80,7 +80,7 @@ public class RestSecurityConfiguration extends 
WebSecurityConfigurerAdapter {
             throws IOException, ServletException {
           response.addHeader("WWW-Authenticate", "Basic realm=\"GEODE\"");
           response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-          response.setContentType(MediaType.APPLICATION_JSON_UTF8.getType());
+          response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
           ClusterManagementResult result =
               new 
ClusterManagementResult(ClusterManagementResult.StatusCode.UNAUTHENTICATED,
                   authException.getMessage());

Reply via email to