You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2019/01/22 21:27:10 UTC

[geode] branch develop updated: GEODE-6283: have the management rest controller call the internal management service

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 a15136a  GEODE-6283: have the management rest controller call the internal management service
a15136a is described below

commit a15136a2de85751ea57afa27d5d0dd91bfb75d91
Author: jinmeiliao <ji...@pivotal.io>
AuthorDate: Tue Jan 22 13:25:41 2019 -0800

    GEODE-6283: have the management rest controller call the internal management service
    
    * GEODE-6283: have the management rest controller call the internal cluster management service to actually create the region
    
    * inject cluster management service to the rest controller
    * have the controller produce json string for response
    * refactor the controller exception handler to always send back json string
---
 .../geode/test/junit/rules/HttpResponseAssert.java |   6 ++
 ...ClusterManagementLocatorReconnectDunitTest.java | 100 +++++++++++++++++++++
 .../internal/rest/RegionManagementDunitTest.java   |  81 +++++++++++++++++
 .../internal/RegionManagementIntegrationTest.java  |  15 +++-
 .../RegionManagementSecurityIntegrationTest.java   |  23 +++--
 .../internal/api/RegionAPIDUnitTest.java           |  12 +--
 .../distributed/internal/InternalLocator.java      |  72 +++++++++++++--
 .../geode/management/internal/JettyHelper.java     |  36 +++++---
 .../geode/management/internal/ManagementAgent.java |  87 +++++++++---------
 .../geode/management/internal/RestAgent.java       |  15 ++--
 .../internal/SystemManagementService.java          |   2 +-
 ...APIResult.java => ClusterManagementResult.java} |  54 ++++++-----
 .../internal/api/ClusterManagementService.java     |  18 ++--
 .../api/LocatorClusterManagementService.java       |  25 +++---
 .../geode/management/internal/api/Status.java      |  45 +++++++---
 .../geode/management/internal/cli/CliUtil.java     |  13 +++
 .../sanctioned-geode-core-serializables.txt        |   2 +-
 ...tTest.java => ClusterManagementResultTest.java} |  51 +++++++----
 .../geode/tools/pulse/tests/rules/ServerRule.java  |   2 +-
 .../controllers/AbstractManagementController.java} |  98 ++++++++++----------
 .../controllers/RegionManagementController.java    |  14 +--
 .../CustomMappingJackson2HttpMessageConverter.java |   2 +-
 .../security/GeodeAuthenticationProvider.java      |   2 +-
 .../security/RestSecurityConfiguration.java        |   6 +-
 .../security/RestSecurityService.java              |   2 +-
 .../webapp/WEB-INF/geode-management-servlet.xml    |   5 +-
 26 files changed, 562 insertions(+), 226 deletions(-)

diff --git a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/HttpResponseAssert.java b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/HttpResponseAssert.java
index 62fb3ba..af9c696 100644
--- a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/HttpResponseAssert.java
+++ b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/HttpResponseAssert.java
@@ -33,6 +33,7 @@ import org.assertj.core.api.AbstractCharSequenceAssert;
 import org.assertj.core.api.ListAssert;
 
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
 
 public class HttpResponseAssert extends AbstractAssert<HttpResponseAssert, HttpResponse> {
   private static Logger logger = LogService.getLogger();
@@ -75,6 +76,11 @@ public class HttpResponseAssert extends AbstractAssert<HttpResponseAssert, HttpR
     return assertThat(responseBody);
   }
 
+  public ClusterManagementResult getClusterManagementResult() throws Exception {
+    ObjectMapper mapper = new ObjectMapper();
+    return mapper.readValue(responseBody, ClusterManagementResult.class);
+  }
+
   public HttpResponseAssert hasContentType(String contentType) {
     assertThat(actual.getEntity().getContentType().getValue()).containsIgnoringCase(contentType);
     return this;
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClusterManagementLocatorReconnectDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClusterManagementLocatorReconnectDunitTest.java
new file mode 100644
index 0000000..2414c46
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClusterManagementLocatorReconnectDunitTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.concurrent.TimeUnit;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+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.management.internal.api.ClusterManagementResult;
+import org.apache.geode.test.dunit.IgnoredException;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GeodeDevRestClient;
+import org.apache.geode.test.junit.rules.RequiresGeodeHome;
+
+public class ClusterManagementLocatorReconnectDunitTest {
+  @Rule
+  public RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
+
+  @Rule
+  public ClusterStartupRule rule = new ClusterStartupRule();
+
+  private MemberVM locator, server;
+
+  private GeodeDevRestClient restClient;
+
+  @Test
+  public void clusterManagementRestServiceStillWorksAfterLocatorReconnects() throws Exception {
+    IgnoredException.addIgnoredException("org.apache.geode.ForcedDisconnectException: for testing");
+    locator = rule.startLocatorVM(0, l -> l.withHttpService());
+    server = rule.startServerVM(1, locator.getPort());
+    restClient =
+        new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false);
+
+    makeRestCallAndVerifyResult("customers");
+
+    locator.forceDisconnect();
+
+    // wait till locator is disconnected and reconnected
+    await().pollInterval(1, TimeUnit.SECONDS).until(() -> locator.invoke("waitTillRestarted",
+        () -> ClusterStartupRule.getLocator().isReconnected()));
+
+    makeRestCallAndVerifyResult("orders");
+  }
+
+  private void makeRestCallAndVerifyResult(String regionName) throws Exception {
+    RegionConfig regionConfig = new RegionConfig();
+    regionConfig.setName(regionName);
+    regionConfig.setRefid("REPLICATE");
+    ObjectMapper mapper = new ObjectMapper();
+    String json = mapper.writeValueAsString(regionConfig);
+
+    ClusterManagementResult result =
+        restClient.doPostAndAssert("/regions", json, "test", "test")
+            .hasStatusCode(201)
+            .getClusterManagementResult();
+
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isTrue();
+    assertThat(result.isSuccessfullyPersisted()).isTrue();
+    assertThat(result.getMemberStatuses()).containsKeys("server-1").hasSize(1);
+
+    // make sure region is created
+    server.invoke(() -> {
+      Region region = ClusterStartupRule.getCache().getRegion(regionName);
+      assertThat(region).isNotNull();
+    });
+
+    // make sure region is persisted
+    locator.invoke(() -> {
+      CacheConfig cacheConfig =
+          ClusterStartupRule.getLocator().getConfigurationPersistenceService()
+              .getCacheConfig("cluster");
+      assertThat(CacheElement.exists(cacheConfig.getRegions(), regionName)).isTrue();
+    });
+
+  }
+
+}
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java
new file mode 100644
index 0000000..85eaf63
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.assertj.core.api.Assertions.assertThat;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GeodeDevRestClient;
+
+public class RegionManagementDunitTest {
+
+  @Rule
+  public ClusterStartupRule cluster = new ClusterStartupRule();
+
+  private MemberVM locator, server;
+
+  private GeodeDevRestClient restClient;
+
+  @Before
+  public void before() throws Exception {
+    locator = cluster.startLocatorVM(0, l -> l.withHttpService());
+    server = cluster.startServerVM(1, locator.getPort());
+    restClient =
+        new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false);
+  }
+
+  @Test
+  public void createRegion() throws Exception {
+    RegionConfig regionConfig = new RegionConfig();
+    regionConfig.setName("customers");
+    regionConfig.setRefid("REPLICATE");
+    ObjectMapper mapper = new ObjectMapper();
+    String json = mapper.writeValueAsString(regionConfig);
+
+    ClusterManagementResult result =
+        restClient.doPostAndAssert("/regions", json, "test", "test")
+            .hasStatusCode(201)
+            .getClusterManagementResult();
+
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isTrue();
+    assertThat(result.isSuccessfullyPersisted()).isTrue();
+    assertThat(result.getMemberStatuses()).containsKeys("server-1").hasSize(1);
+
+    // make sure region is created
+    server.invoke(() -> {
+      Region region = ClusterStartupRule.getCache().getRegion("customers");
+      assertThat(region).isNotNull();
+    });
+
+    // make sure region is persisted
+    locator.invoke(() -> {
+      CacheConfig cacheConfig =
+          ClusterStartupRule.getLocator().getConfigurationPersistenceService()
+              .getCacheConfig("cluster");
+      assertThat(cacheConfig.getRegions().get(0).getName()).isEqualTo("customers");
+    });
+  }
+}
diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java
index b7ad609..7e0a8a2 100644
--- a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java
+++ b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java
@@ -15,12 +15,15 @@
 
 package org.apache.geode.management.internal;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
 
 import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
 import org.apache.geode.test.junit.rules.GeodeDevRestClient;
 import org.apache.geode.test.junit.rules.LocatorStarterRule;
 import org.apache.geode.test.junit.rules.RequiresGeodeHome;
@@ -51,8 +54,14 @@ public class RegionManagementIntegrationTest {
     ObjectMapper mapper = new ObjectMapper();
     String json = mapper.writeValueAsString(regionConfig);
 
-    restClient.doPostAndAssert("/regions", json, null, null)
-        .hasStatusCode(201)
-        .hasResponseBody().isEqualTo("customers");
+    ClusterManagementResult result =
+        restClient.doPostAndAssert("/regions", json, null, null)
+            .hasStatusCode(500)
+            .getClusterManagementResult();
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.isSuccessfullyPersisted()).isFalse();
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isFalse();
+    assertThat(result.getPersistenceStatus().getMessage())
+        .isEqualTo("no members found to create cache element");
   }
 }
diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java
index 6351faa..ed991d0 100644
--- a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java
+++ b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java
@@ -15,6 +15,8 @@
 
 package org.apache.geode.management.internal;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Before;
@@ -23,6 +25,7 @@ import org.junit.ClassRule;
 import org.junit.Test;
 
 import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
 import org.apache.geode.security.SimpleTestSecurityManager;
 import org.apache.geode.test.junit.rules.GeodeDevRestClient;
 import org.apache.geode.test.junit.rules.LocatorStarterRule;
@@ -59,9 +62,12 @@ public class RegionManagementSecurityIntegrationTest {
 
   @Test
   public void sanityCheck_not_authorized() throws Exception {
-    restClient.doPostAndAssert("/regions", json, "test", "test")
-        .hasStatusCode(403)
-        .hasResponseBody().isEqualTo("Access is denied");
+    ClusterManagementResult result =
+        restClient.doPostAndAssert("/regions", json, "test", "test")
+            .hasStatusCode(403)
+            .getClusterManagementResult();
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.getPersistenceStatus().getMessage()).isEqualTo("Access is denied");
   }
 
   @Test
@@ -78,9 +84,12 @@ public class RegionManagementSecurityIntegrationTest {
 
   @Test
   public void sanityCheck_success() throws Exception {
-    restClient.doPostAndAssert("/regions", json, "dataManage", "dataManage")
-        .hasStatusCode(201)
-        .hasResponseBody().isEqualTo("customers");
+    ClusterManagementResult result =
+        restClient.doPostAndAssert("/regions", json, "dataManage", "dataManage")
+            .hasStatusCode(500)
+            .getClusterManagementResult();
+    assertThat(result.isSuccessful()).isFalse();
+    assertThat(result.getPersistenceStatus().getMessage())
+        .isEqualTo("no members found to create cache element");
   }
-
 }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/api/RegionAPIDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/api/RegionAPIDUnitTest.java
index 5d2ce1a..b685fdd 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/api/RegionAPIDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/api/RegionAPIDUnitTest.java
@@ -65,8 +65,8 @@ public class RegionAPIDUnitTest {
       RegionConfig config = new RegionConfig();
       config.setName(regionName);
       config.setRefid(RegionShortcut.PARTITION.toString());
-      APIResult result = ClusterStartupRule.getLocator().getClusterManagementService()
-          .createCacheElement(config);
+      ClusterManagementResult result = ClusterStartupRule.getLocator().getClusterManagementService()
+          .create(config);
       assertThat(result.isSuccessful()).isTrue();
     });
 
@@ -98,8 +98,8 @@ public class RegionAPIDUnitTest {
       RegionConfig config = new RegionConfig();
       config.setName(regionName);
       config.setRefid(RegionShortcut.REPLICATE.toString());
-      APIResult result = ClusterStartupRule.getLocator().getClusterManagementService()
-          .createCacheElement(config);
+      ClusterManagementResult result = ClusterStartupRule.getLocator().getClusterManagementService()
+          .create(config);
       assertThat(result.isSuccessful()).isTrue();
     });
 
@@ -123,8 +123,8 @@ public class RegionAPIDUnitTest {
       RegionConfig config = new RegionConfig();
       config.setName(regionName);
       config.setRefid(RegionShortcut.PARTITION.toString());
-      APIResult result = ClusterStartupRule.getLocator().getClusterManagementService()
-          .createCacheElement(config);
+      ClusterManagementResult result = ClusterStartupRule.getLocator().getClusterManagementService()
+          .create(config);
       assertThat(result.isSuccessful()).isTrue();
     });
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
index 517ceb4..f26342e 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
@@ -36,7 +36,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.logging.log4j.Logger;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import org.apache.geode.CancelException;
 import org.apache.geode.cache.CacheFactory;
@@ -61,6 +64,7 @@ import org.apache.geode.distributed.internal.tcpserver.LocatorCancelException;
 import org.apache.geode.distributed.internal.tcpserver.TcpClient;
 import org.apache.geode.distributed.internal.tcpserver.TcpHandler;
 import org.apache.geode.distributed.internal.tcpserver.TcpServer;
+import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.admin.remote.DistributionLocatorId;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
@@ -78,8 +82,12 @@ import org.apache.geode.internal.logging.NullLoggingSession;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.management.internal.AgentUtil;
+import org.apache.geode.management.internal.JettyHelper;
 import org.apache.geode.management.internal.JmxManagerLocator;
 import org.apache.geode.management.internal.JmxManagerLocatorRequest;
+import org.apache.geode.management.internal.ManagementAgent;
+import org.apache.geode.management.internal.SystemManagementService;
 import org.apache.geode.management.internal.api.ClusterManagementService;
 import org.apache.geode.management.internal.api.LocatorClusterManagementService;
 import org.apache.geode.management.internal.configuration.domain.SharedConfigurationStatus;
@@ -191,6 +199,7 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
   private final LoggingSession loggingSession;
 
   private final Set<LogConfigListener> logConfigListeners = new HashSet<>();
+  private WebAppContext managementWebapp;
 
   public boolean isSharedConfigurationEnabled() {
     return this.config.getEnableClusterConfiguration();
@@ -662,9 +671,50 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
     }
     startJmxManagerLocationService(internalCache);
 
-    startSharedConfigurationService();
-    clusterManagementService = new LocatorClusterManagementService(locator.myCache,
-        locator.configurationPersistenceService);
+    startClusterManagementService();
+  }
+
+  private void startClusterManagementService() {
+    startConfigurationPersistenceService();
+
+    if (myCache == null) {
+      return;
+    }
+
+    clusterManagementService =
+        new LocatorClusterManagementService(locator.myCache.getDistributionManager(),
+            locator.configurationPersistenceService);
+
+    // start management rest service
+    AgentUtil agentUtil = new AgentUtil(GemFireVersion.getGemFireVersion());
+    // Find the V2 Management rest WAR file
+    final String gemfireManagementWar = agentUtil.findWarLocation("geode-web-management");
+    if (gemfireManagementWar == null) {
+      logger.info(
+          "Unable to find GemFire V2 Management REST API WAR file; the Management REST Interface for Geode will not be accessible.");
+      return;
+    }
+
+    ManagementAgent managementAgent =
+        ((SystemManagementService) SystemManagementService.getExistingManagementService(myCache))
+            .getManagementAgent();
+
+    if (managementAgent == null) {
+      logger.info(
+          "management service needs to be started for ClusterManagementService to be running.");
+      return;
+    }
+
+    Pair<String, Object> securityServiceAttr =
+        new ImmutablePair<>(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
+            myCache.getSecurityService());
+    Pair<String, Object> cmServiceAttr =
+        new ImmutablePair<>(JettyHelper.CLUSTER_MANAGEMENT_SERVICE_CONTEXT_PARAM,
+            clusterManagementService);
+    managementWebapp =
+        managementAgent
+            .addWebApplication("/geode-management", gemfireManagementWar, securityServiceAttr,
+                cmServiceAttr);
   }
 
   /**
@@ -820,6 +870,15 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
       }
     }
 
+    // stop the managementwebapp
+    if (managementWebapp != null) {
+      try {
+        managementWebapp.stop();
+      } catch (Exception e) {
+        logger.error("unable to stop the management webapp.", e);
+      }
+    }
+
     removeLocator(this);
 
     handleShutdown();
@@ -849,6 +908,7 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
     if (this.myDs != null) {
       this.myDs.setDependentLocator(null);
     }
+
     if (this.myCache != null && !this.stoppedForReconnect && !this.forcedDisconnect) {
       logger.info("Closing locator's cache");
       try {
@@ -1039,10 +1099,8 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
       if (isSharedConfigurationEnabled()) {
         this.configurationPersistenceService =
             new InternalConfigurationPersistenceService(newCache);
-        startSharedConfigurationService();
+        startClusterManagementService();
       }
-      this.clusterManagementService = new LocatorClusterManagementService(this.myCache,
-          this.configurationPersistenceService);
       if (!this.server.isAlive()) {
         logger.info("Locator restart: starting TcpServer");
         startTcpServer();
@@ -1338,7 +1396,7 @@ public class InternalLocator extends Locator implements ConnectListener, LogConf
     }
   }
 
-  private void startSharedConfigurationService() {
+  private void startConfigurationPersistenceService() {
     installSharedConfigHandler();
 
     if (!config.getEnableClusterConfiguration()) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java b/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
index 34f5d91..afbb051 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/JettyHelper.java
@@ -15,11 +15,12 @@
 package org.apache.geode.management.internal;
 
 import java.io.File;
-import java.util.Properties;
+import java.util.Arrays;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.logging.log4j.Logger;
 import org.eclipse.jetty.http.HttpVersion;
 import org.eclipse.jetty.server.Connector;
@@ -37,7 +38,6 @@ 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.internal.security.SecurityService;
 
 /**
  * @since GemFire 8.1
@@ -60,7 +60,9 @@ public class JettyHelper {
   public static final String SECURITY_SERVICE_SERVLET_CONTEXT_PARAM =
       "org.apache.geode.securityService";
 
-  private static final String GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM = "org.apache.geode.sslConfig";
+  public static final String GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM = "org.apache.geode.sslConfig";
+  public static final String CLUSTER_MANAGEMENT_SERVICE_CONTEXT_PARAM =
+      "org.apache.geode.sslConfig";
 
   public static Server initJetty(final String bindAddress, final int port, SSLConfig sslConfig) {
 
@@ -68,7 +70,7 @@ public class JettyHelper {
 
     // Add a handler collection here, so that each new context adds itself
     // to this collection.
-    jettyServer.setHandler(new HandlerCollection());
+    jettyServer.setHandler(new HandlerCollection(true));
     ServerConnector connector = null;
 
     HttpConfiguration httpConfig = new HttpConfiguration();
@@ -166,27 +168,35 @@ public class JettyHelper {
     return jetty;
   }
 
-  public static Server addWebApplication(final Server jetty, final String webAppContext,
-      final String warFilePath, SecurityService securityService, Properties sslConfig) {
+  public static WebAppContext addWebApplication(final Server jetty, final String webAppContext,
+      final String warFilePath,
+      Pair<String, Object>... attributeNameValuePairs) {
     WebAppContext webapp = new WebAppContext();
     webapp.setContextPath(webAppContext);
     webapp.setWar(warFilePath);
     webapp.setParentLoaderPriority(false);
     webapp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
-    webapp.setAttribute(SECURITY_SERVICE_SERVLET_CONTEXT_PARAM, securityService);
     webapp.addAliasCheck(new AllowSymLinkAliasChecker());
 
-    // This is only required for Pulse because in embedded mode, with SSL enabled, Pulse needs to
-    // know how to make SSL RMI connections.
-    webapp.setAttribute(GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM, sslConfig);
+    if (attributeNameValuePairs != null) {
+      Arrays.stream(attributeNameValuePairs)
+          .forEach(p -> webapp.setAttribute(p.getKey(), p.getValue()));
+    }
 
     File tmpPath = new File(getWebAppBaseDirectory(webAppContext));
     tmpPath.mkdirs();
     webapp.setTempDirectory(tmpPath);
-
     ((HandlerCollection) jetty.getHandler()).addHandler(webapp);
-
-    return jetty;
+    // if we are adding this webapp after the jetty server has already started, we will need to
+    // manually start the webapp.
+    if (jetty.isStarted()) {
+      try {
+        webapp.start();
+      } catch (Exception e) {
+        logger.error(e.getMessage(), e);
+      }
+    }
+    return webapp;
   }
 
   private static String getWebAppBaseDirectory(final String context) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
index b37c1d5..62cb055 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java
@@ -44,18 +44,19 @@ import javax.management.remote.rmi.RMIServerImpl;
 
 import com.healthmarketscience.rmiio.exporter.RemoteStreamExporter;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.logging.log4j.Logger;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import org.apache.geode.GemFireConfigException;
-import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.admin.SSLConfig;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.InternalCacheForClientAccess;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.net.SSLConfigurationFactory;
 import org.apache.geode.internal.net.SocketCreator;
@@ -98,6 +99,7 @@ public class ManagementAgent {
   private JMXShiroAuthenticator shiroAuthenticator;
   private final DistributionConfig config;
   private final SecurityService securityService;
+  private final InternalCache cache;
   private boolean isHttpServiceRunning = false;
   private RMIClientSocketFactory rmiClientSocketFactory;
   private RMIServerSocketFactory rmiServerSocketFactory;
@@ -114,9 +116,10 @@ public class ManagementAgent {
   private static final String PULSE_USESSL_MANAGER = "pulse.useSSL.manager";
   private static final String PULSE_USESSL_LOCATOR = "pulse.useSSL.locator";
 
-  public ManagementAgent(DistributionConfig config, SecurityService securityService) {
+  public ManagementAgent(DistributionConfig config, InternalCache cache) {
     this.config = config;
-    this.securityService = securityService;
+    this.cache = cache;
+    this.securityService = cache.getSecurityService();
   }
 
   public synchronized boolean isRunning() {
@@ -143,14 +146,6 @@ public class ManagementAgent {
         && !cache.isClient());
   }
 
-  public static InternalCacheForClientAccess getCache() {
-    InternalCache cache = (InternalCache) CacheFactory.getAnyInstance();
-    if (cache != null) {
-      return cache.getCacheForProcessingClientRequests();
-    }
-    return null;
-  }
-
   public synchronized void startAgent(InternalCache cache) {
     // Do not start Management REST service if developer REST service is already
     // started.
@@ -194,13 +189,26 @@ public class ManagementAgent {
     this.running = false;
   }
 
+  public WebAppContext addWebApplication(String webAppContext, String warFilePath,
+      Pair<String, Object>... attributeNameValuePairs) {
+    if (httpServer == null) {
+      logger.info(
+          String.format("unable to add %s webapp. Http service is not started on this member.",
+              webAppContext));
+      return null;
+    }
+
+    return JettyHelper
+        .addWebApplication(httpServer, webAppContext, warFilePath, attributeNameValuePairs);
+  }
+
   private Server httpServer;
   private final String GEMFIRE_VERSION = GemFireVersion.getGemFireVersion();
   private final AgentUtil agentUtil = new AgentUtil(GEMFIRE_VERSION);
 
   private void startHttpService(boolean isServer) {
     final SystemManagementService managementService = (SystemManagementService) ManagementService
-        .getManagementService(getCache());
+        .getManagementService(cache);
 
     final ManagerMXBean managerBean = managementService.getManagerMXBean();
 
@@ -215,16 +223,7 @@ public class ManagementAgent {
       if (gemfireWar == null) {
         if (logger.isDebugEnabled()) {
           logger.debug(
-              "Unable to find GemFire V1 Management REST API WAR file; the Management REST Interface for GemFire will not be accessible.");
-        }
-      }
-
-      // Find the V2 Management rest WAR file
-      final String gemfireManagementWar = agentUtil.findWarLocation("geode-web-management");
-      if (gemfireManagementWar == null) {
-        if (logger.isDebugEnabled()) {
-          logger.debug(
-              "Unable to find GemFire V2 Management REST API WAR file; the Management REST Interface for GemFire will not be accessible.");
+              "Unable to find Geode V1 Management REST API WAR file; the Management REST Interface for Geode will not be accessible.");
         }
       }
 
@@ -233,7 +232,7 @@ public class ManagementAgent {
 
       if (pulseWar == null) {
         final String message =
-            "Unable to find Pulse web application WAR file; Pulse for GemFire will not be accessible";
+            "Unable to find Pulse web application WAR file; Pulse for Geode will not be accessible";
         setStatusMessage(managerBean, message);
         if (logger.isDebugEnabled()) {
           logger.debug(message);
@@ -249,7 +248,7 @@ public class ManagementAgent {
       final String gemfireAPIWar = agentUtil.findWarLocation("geode-web-api");
       if (gemfireAPIWar == null) {
         final String message =
-            "Unable to find GemFire Developer REST API WAR file; the Developer REST Interface for GemFire will not be accessible.";
+            "Unable to find Geode Developer REST API WAR file; the Developer REST Interface for Geode will not be accessible.";
         setStatusMessage(managerBean, message);
         if (logger.isDebugEnabled()) {
           logger.debug(message);
@@ -257,8 +256,7 @@ public class ManagementAgent {
       }
 
       try {
-        if (agentUtil.isAnyWarFileAvailable(gemfireWar, gemfireManagementWar, pulseWar,
-            gemfireAPIWar)) {
+        if (agentUtil.isAnyWarFileAvailable(gemfireWar, pulseWar, gemfireAPIWar)) {
 
           final String bindAddress = this.config.getHttpServiceBindAddress();
           final int port = this.config.getHttpServicePort();
@@ -268,29 +266,30 @@ public class ManagementAgent {
           this.httpServer = JettyHelper.initJetty(bindAddress, port, SSLConfigurationFactory
               .getSSLConfigForComponent(config, SecurableCommunicationChannel.WEB));
 
-          if (agentUtil.isAnyWarFileAvailable(gemfireWar)) {
-            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire", gemfireWar,
-                securityService, null);
-            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode-mgmt",
-                gemfireWar, securityService, null);
-          }
+          Pair<String, Object> securityServiceAttr =
+              new ImmutablePair<>(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
+                  securityService);
+          Pair<String, Object> sslConfigAttr =
+              new ImmutablePair<>(JettyHelper.GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM,
+                  createSslProps());
 
-          if (agentUtil.isAnyWarFileAvailable(gemfireManagementWar)) {
-            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode-management",
-                gemfireManagementWar, securityService, null);
+          // if jmx manager is running, admin rest should be available, either on locator or server
+          if (agentUtil.isAnyWarFileAvailable(gemfireWar)) {
+            addWebApplication("/gemfire", gemfireWar, securityServiceAttr);
+            addWebApplication("/geode-mgmt", gemfireWar, securityServiceAttr);
           }
 
+          // if jmx manager is running, pulse should be available, either on locator or server
+          // we need to pass in the sllConfig to pulse because it needs it to make jmx connection
           if (agentUtil.isAnyWarFileAvailable(pulseWar)) {
-            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/pulse", pulseWar,
-                securityService, createSslProps());
+            addWebApplication("/pulse", pulseWar, securityServiceAttr, sslConfigAttr);
           }
 
+          // the dev rest api is only available on servers
           if (isServer && this.config.getStartDevRestApi()) {
             if (agentUtil.isAnyWarFileAvailable(gemfireAPIWar)) {
-              this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode",
-                  gemfireAPIWar, securityService, null);
-              this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire-api",
-                  gemfireAPIWar, securityService, null);
+              addWebApplication("/geode", gemfireAPIWar, securityServiceAttr);
+              addWebApplication("/gemfire-api", gemfireAPIWar, securityServiceAttr);
               isRestWebAppAdded = true;
             }
           } else {
@@ -329,9 +328,7 @@ public class ManagementAgent {
 
           // set cache property for developer REST service running
           if (isRestWebAppAdded) {
-            InternalCache cache = getCache();
             cache.setRESTServiceRunning(true);
-
             // create region to hold query information (queryId, queryString).
             // Added for the developer REST APIs
             RestAgent.createParameterizedQueryRegion();
@@ -419,7 +416,7 @@ public class ManagementAgent {
         try {
           this.httpServer.destroy();
         } catch (Exception ignore) {
-          logger.error("Failed to properly release resources held by the HTTP service: {}",
+          logger.info("Failed to properly release resources held by the HTTP service: {}",
               ignore.getMessage(), ignore);
         } finally {
           this.httpServer = null;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
index 6405c52..26af1b6 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/RestAgent.java
@@ -17,6 +17,8 @@ package org.apache.geode.management.internal;
 import java.net.UnknownHostException;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.logging.log4j.Logger;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
@@ -137,10 +139,13 @@ public class RestAgent {
         this.httpServer = JettyHelper.initJetty(httpServiceBindAddress, port,
             SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.WEB));
 
-        this.httpServer = JettyHelper.addWebApplication(httpServer, "/gemfire-api", gemfireAPIWar,
-            securityService, null);
-        this.httpServer = JettyHelper.addWebApplication(httpServer, "/geode", gemfireAPIWar,
-            securityService, null);
+        Pair<String, Object> securityServiceAttr =
+            new ImmutablePair<>(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
+                securityService);
+
+        JettyHelper
+            .addWebApplication(httpServer, "/gemfire-api", gemfireAPIWar, securityServiceAttr);
+        JettyHelper.addWebApplication(httpServer, "/geode", gemfireAPIWar, securityServiceAttr);
 
         if (logger.isDebugEnabled()) {
           logger.debug("Starting HTTP embedded server on port ({}) at bind-address ({})...",
@@ -148,7 +153,7 @@ public class RestAgent {
               httpServiceBindAddress);
         }
 
-        this.httpServer = JettyHelper.startJetty(this.httpServer);
+        JettyHelper.startJetty(this.httpServer);
         logger.info("HTTP service started successfully...!!");
       }
     } catch (Exception e) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
index 0ffa38d..281d889 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
@@ -140,7 +140,7 @@ public class SystemManagementService extends BaseManagementService {
 
     this.notificationHub = new NotificationHub(repo);
     if (system.getConfig().getJmxManager()) {
-      this.agent = new ManagementAgent(system.getConfig(), cache.getSecurityService());
+      this.agent = new ManagementAgent(system.getConfig(), cache);
     } else {
       this.agent = null;
     }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/APIResult.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementResult.java
similarity index 54%
rename from geode-core/src/main/java/org/apache/geode/management/internal/api/APIResult.java
rename to geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementResult.java
index 300b3b0..829dfb3 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/api/APIResult.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementResult.java
@@ -17,47 +17,51 @@ package org.apache.geode.management.internal.api;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 
-public class APIResult {
-  enum Result {
-    SUCCESS, FAILURE, NOT_APPLICABLE
-  }
 
-  class Status {
-    Result result;
-    String message;
+public class ClusterManagementResult {
+  private Map<String, Status> memberStatuses = new HashMap<>();
 
-    public Status(Result result, String message) {
-      this.result = result;
-      this.message = message;
-    }
-  }
+  private Status persistenceStatus = new Status(Status.Result.NOT_APPLICABLE, null);
 
-  private Map<String, Status> memberStatuses = new HashMap<>();
-  private Status clusterConfigStatus = new Status(Result.NOT_APPLICABLE, null);
+  public ClusterManagementResult() {}
 
-  public void addMemberStatus(String member, Result result, String message) {
+  public ClusterManagementResult(boolean success, String message) {
+    this.persistenceStatus = new Status(success, message);
+  }
+
+  public void addMemberStatus(String member, Status.Result result, String message) {
     this.memberStatuses.put(member, new Status(result, message));
   }
 
-  public void setClusterConfigPersisted(Result result, String message) {
-    this.clusterConfigStatus = new Status(result, message);
+  public void addMemberStatus(String member, boolean success, String message) {
+    this.memberStatuses.put(member, new Status(success, message));
+  }
+
+  public void setClusterConfigPersisted(boolean success, String message) {
+    this.persistenceStatus = new Status(success, message);
   }
 
   public Map<String, Status> getMemberStatuses() {
     return memberStatuses;
   }
 
-  public Status getClusterConfigStatus() {
-    return clusterConfigStatus;
+  public Status getPersistenceStatus() {
+    return persistenceStatus;
   }
 
-  public boolean isSuccessfulOnDistributedMembers() {
-    return memberStatuses.values().stream().allMatch(x -> x.result == Result.SUCCESS);
+  @JsonIgnore
+  public boolean isSuccessfullyAppliedOnMembers() {
+    if (memberStatuses.isEmpty()) {
+      return false;
+    }
+    return memberStatuses.values().stream().allMatch(x -> x.status == Status.Result.SUCCESS);
   }
 
+  @JsonIgnore
   public boolean isSuccessfullyPersisted() {
-    return clusterConfigStatus.result == Result.SUCCESS;
+    return persistenceStatus.status == Status.Result.SUCCESS;
   }
 
   /**
@@ -66,8 +70,10 @@ public class APIResult {
    * or configuration persistence is applicable and successful
    * - false otherwise
    */
+  @JsonIgnore
   public boolean isSuccessful() {
-    return (clusterConfigStatus.result == Result.NOT_APPLICABLE || isSuccessfullyPersisted())
-        && isSuccessfulOnDistributedMembers();
+    return (persistenceStatus.status == Status.Result.NOT_APPLICABLE || isSuccessfullyPersisted())
+        && isSuccessfullyAppliedOnMembers();
   }
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementService.java
index ead9092..e3c82e4 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/ClusterManagementService.java
@@ -19,15 +19,21 @@ import org.apache.geode.annotations.Experimental;
 import org.apache.geode.cache.configuration.CacheElement;
 
 /**
- * Defines the behavior for a management service object, which is responsible for applying and
- * persisting
- * cache configuaration changes on locators and/or servers.
+ * this is responsible for applying and persisting cache configuration changes on locators
+ * and/or servers.
  */
 @Experimental
 public interface ClusterManagementService {
-  APIResult createCacheElement(CacheElement config);
+  /**
+   * This method will try to create the element on all the applicable members in the cluster and
+   * persist the configuration in the cluster configuration if persistence is enabled.
+   *
+   * @param config this holds the configuration attributes of the element you are trying to create
+   *        on the cluster
+   */
+  ClusterManagementResult create(CacheElement config);
 
-  APIResult deleteCacheElement(CacheElement config);
+  ClusterManagementResult delete(CacheElement config);
 
-  APIResult updateCacheElement(CacheElement config);
+  ClusterManagementResult update(CacheElement config);
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
index 8ad72b6..b745251 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
@@ -30,7 +30,7 @@ import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.distributed.ConfigurationPersistenceService;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
@@ -42,19 +42,18 @@ import org.apache.geode.management.internal.exceptions.NoMembersException;
 
 public class LocatorClusterManagementService implements ClusterManagementService {
   private static Logger logger = LogService.getLogger();
-  private InternalCache cache;
+  private DistributionManager distributionManager;
   private ConfigurationPersistenceService persistenceService;
 
-  public LocatorClusterManagementService(InternalCache cache,
+  public LocatorClusterManagementService(DistributionManager distributionManager,
       ConfigurationPersistenceService persistenceService) {
-    this.cache = cache;
+    this.distributionManager = distributionManager;
     this.persistenceService = persistenceService;
-
   }
 
   @Override
-  public APIResult createCacheElement(CacheElement config) {
-    APIResult result = new APIResult();
+  public ClusterManagementResult create(CacheElement config) {
+    ClusterManagementResult result = new ClusterManagementResult();
     String group = "cluster";
     ConfigurationMutator configurationMutator =
         (new ConfigurationMutatorFactory()).generate(config);
@@ -80,7 +79,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
         targetedMembers);
     functionResults
         .forEach(functionResult -> result.addMemberStatus(functionResult.getMemberIdOrName(),
-            functionResult.isSuccessful() ? APIResult.Result.SUCCESS : APIResult.Result.FAILURE,
+            functionResult.isSuccessful(),
             functionResult.getStatusMessage()));
 
     // persist configuration in cache config
@@ -88,12 +87,12 @@ public class LocatorClusterManagementService implements ClusterManagementService
       persistenceService.updateCacheConfig(group, cacheConfigForGroup -> {
         try {
           configurationMutator.add(config, cacheConfigForGroup);
-          result.setClusterConfigPersisted(APIResult.Result.SUCCESS,
+          result.setClusterConfigPersisted(true,
               "successfully persisted config for " + group);
         } catch (Exception e) {
           String message = "failed to update cluster config for " + group;
           logger.error(message, e);
-          result.setClusterConfigPersisted(APIResult.Result.FAILURE, message);
+          result.setClusterConfigPersisted(false, message);
           return null;
         }
 
@@ -105,17 +104,17 @@ public class LocatorClusterManagementService implements ClusterManagementService
   }
 
   @Override
-  public APIResult deleteCacheElement(CacheElement config) {
+  public ClusterManagementResult delete(CacheElement config) {
     throw new NotImplementedException();
   }
 
   @Override
-  public APIResult updateCacheElement(CacheElement config) {
+  public ClusterManagementResult update(CacheElement config) {
     throw new NotImplementedException();
   }
 
   private Set<DistributedMember> findMembers(String[] groups, String[] members) {
-    return CliUtil.findMembers(groups, members, cache);
+    return CliUtil.findMembers(groups, members, distributionManager);
   }
 
   private List<CliFunctionResult> executeAndGetFunctionResult(Function function, Object args,
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/Status.java
similarity index 52%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java
rename to geode-core/src/main/java/org/apache/geode/management/internal/api/Status.java
index 9fbb1c7..1866dc2 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/Status.java
@@ -12,25 +12,44 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
+package org.apache.geode.management.internal.api;
 
-package org.apache.geode.management.internal.web.controllers;
+public class Status {
+  enum Result {
+    SUCCESS, FAILURE, NOT_APPLICABLE
+  }
 
-import javax.servlet.ServletContext;
+  Result status;
+  String message;
 
-import org.springframework.web.context.ServletContextAware;
+  // needed for json deserialization
+  public Status() {}
 
-import org.apache.geode.internal.security.SecurityService;
-import org.apache.geode.management.internal.JettyHelper;
+  ;
 
-public class AbstractManagementController extends AbstractAdminRestController implements
-    ServletContextAware {
+  public Status(Result status, String message) {
+    this.status = status;
+    this.message = message;
+  }
 
-  protected static final String MANAGEMENT_API_VERSION = "/v2";
-  protected SecurityService securityService;
+  public Status(boolean success, String message) {
+    this.status = success ? Result.SUCCESS : Result.FAILURE;
+    this.message = message;
+  }
+
+  public Result getStatus() {
+    return status;
+  }
+
+  public void setStatus(Result status) {
+    this.status = status;
+  }
+
+  public String getMessage() {
+    return message;
+  }
 
-  @Override
-  public void setServletContext(ServletContext servletContext) {
-    securityService = (SecurityService) servletContext
-        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  public void setMessage(String message) {
+    this.message = message;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
index 2a6f13d..589b9eb 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
@@ -48,6 +48,7 @@ import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.ClassPathLoader;
@@ -262,6 +263,18 @@ public class CliUtil {
     return findMembers(allNormalMembers, groups, members);
   }
 
+  /**
+   * Finds all Servers which belong to the given arrays of groups or members. Does not include
+   * locators.
+   */
+  public static Set<DistributedMember> findMembers(String[] groups, String[] members,
+      DistributionManager distributionManager) {
+    Set<DistributedMember> allNormalMembers = new HashSet<DistributedMember>(
+        distributionManager.getNormalDistributionManagerIds());
+
+    return findMembers(allNormalMembers, groups, members);
+  }
+
   private static Set<DistributedMember> findMembers(Set<DistributedMember> membersToConsider,
       String[] groups, String[] members) {
     if (groups == null) {
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 0bc47a9..feacecf 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
@@ -497,7 +497,7 @@ org/apache/geode/management/internal/JmxManagerLocator$StartJmxManagerFunction,t
 org/apache/geode/management/internal/ManagementAgent$GemFireRMIServerSocketFactory,true,-811909050641332716,bindAddr:java/net/InetAddress
 org/apache/geode/management/internal/ManagementFunction,true,1,mbeanServer:javax/management/MBeanServer,notificationHub:org/apache/geode/management/internal/NotificationHub
 org/apache/geode/management/internal/NotificationKey,false,currentTime:long,objectName:javax/management/ObjectName
-org/apache/geode/management/internal/api/APIResult$Result,false
+org/apache/geode/management/internal/api/Status$Result,false0
 org/apache/geode/management/internal/beans/FileUploader$RemoteFile,false,filename:java/lang/String,outputStream:com/healthmarketscience/rmiio/RemoteOutputStream
 org/apache/geode/management/internal/beans/QueryDataFunction,true,1
 org/apache/geode/management/internal/beans/QueryDataFunction$LocalQueryFunction,true,1,id:java/lang/String,optimizeForWrite:boolean,regionName:java/lang/String,showMembers:boolean,this$0:org/apache/geode/management/internal/beans/QueryDataFunction
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/api/APIResultTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/api/ClusterManagementResultTest.java
similarity index 52%
rename from geode-core/src/test/java/org/apache/geode/management/internal/api/APIResultTest.java
rename to geode-core/src/test/java/org/apache/geode/management/internal/api/ClusterManagementResultTest.java
index ef56d79..57acc1d 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/api/APIResultTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/api/ClusterManagementResultTest.java
@@ -19,34 +19,53 @@ package org.apache.geode.management.internal.api;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import org.junit.Before;
 import org.junit.Test;
 
-public class APIResultTest {
+public class ClusterManagementResultTest {
+  private ClusterManagementResult result;
+
+  @Before
+  public void setup() {
+    result = new ClusterManagementResult();
+  }
+
   @Test
-  public void successfulOnlyWhenResultIsSuccessfulOnAllMembers() {
-    APIResult result = new APIResult();
-    result.addMemberStatus("member-1", APIResult.Result.SUCCESS, "msg-1");
-    result.addMemberStatus("member-2", APIResult.Result.FAILURE, "msg-2");
-    assertThat(result.isSuccessfulOnDistributedMembers()).isFalse();
+  public void failsWhenNotAppliedOnAllMembers() {
+    result.addMemberStatus("member-1", true, "msg-1");
+    result.addMemberStatus("member-2", false, "msg-2");
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isFalse();
     assertThat(result.isSuccessful()).isFalse();
+  }
 
-    result = new APIResult();
-    result.addMemberStatus("member-1", APIResult.Result.SUCCESS, "msg-1");
-    result.addMemberStatus("member-2", APIResult.Result.SUCCESS, "msg-2");
-    assertThat(result.isSuccessfulOnDistributedMembers()).isTrue();
+  @Test
+  public void successfulOnlyWhenResultIsSuccessfulOnAllMembers() {
+    result.addMemberStatus("member-1", true, "msg-1");
+    result.addMemberStatus("member-2", true, "msg-2");
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isTrue();
     assertThat(result.isSuccessful()).isTrue();
   }
 
   @Test
-  public void successfulOnlyWhenClusterConfigIsPersisted() {
-    APIResult result = new APIResult();
-    result.setClusterConfigPersisted(APIResult.Result.FAILURE, "msg-1");
+  public void emptyMemberStatus() {
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isFalse();
     assertThat(result.isSuccessfullyPersisted()).isFalse();
     assertThat(result.isSuccessful()).isFalse();
+  }
+
 
-    result = new APIResult();
-    result.setClusterConfigPersisted(APIResult.Result.SUCCESS, "msg-1");
+  @Test
+  public void failsWhenNotPersisted() {
+    result.setClusterConfigPersisted(false, "msg-1");
+    assertThat(result.isSuccessfullyPersisted()).isFalse();
+    assertThat(result.isSuccessful()).isFalse();
+  }
+
+  @Test
+  public void failsWhenNoMembersExists() {
+    result.setClusterConfigPersisted(true, "msg-1");
     assertThat(result.isSuccessfullyPersisted()).isTrue();
-    assertThat(result.isSuccessful()).isTrue();
+    assertThat(result.isSuccessfullyAppliedOnMembers()).isFalse();
+    assertThat(result.isSuccessful()).isFalse();
   }
 }
diff --git a/geode-pulse/geode-pulse-test/src/main/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java b/geode-pulse/geode-pulse-test/src/main/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
index df6a053..509ad6f 100644
--- a/geode-pulse/geode-pulse-test/src/main/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
+++ b/geode-pulse/geode-pulse-test/src/main/java/org/apache/geode/tools/pulse/tests/rules/ServerRule.java
@@ -80,7 +80,7 @@ public class ServerRule extends ExternalResource {
 
     int httpPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
     jetty = JettyHelper.initJetty(LOCALHOST, httpPort, new SSLConfig());
-    JettyHelper.addWebApplication(jetty, PULSE_CONTEXT, getPulseWarPath(), null, null);
+    JettyHelper.addWebApplication(jetty, PULSE_CONTEXT, getPulseWarPath());
     pulseURL = "http://" + LOCALHOST + ":" + httpPort + PULSE_CONTEXT;
     System.out.println("Pulse started at " + pulseURL);
     jetty.start();
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractAdminRestController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/AbstractManagementController.java
similarity index 51%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractAdminRestController.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/AbstractManagementController.java
index fa37da7..e03e713 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractAdminRestController.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/AbstractManagementController.java
@@ -12,13 +12,12 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.web.controllers;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
+package org.apache.geode.management.internal.rest.controllers;
 
 import javax.management.InstanceNotFoundException;
 import javax.management.MalformedObjectNameException;
+import javax.servlet.ServletContext;
 
 import org.apache.logging.log4j.Logger;
 import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
@@ -28,59 +27,64 @@ import org.springframework.security.access.AccessDeniedException;
 import org.springframework.web.bind.WebDataBinder;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.context.ServletContextAware;
 
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.management.MemberMXBean;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.management.internal.JettyHelper;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
+import org.apache.geode.management.internal.api.LocatorClusterManagementService;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.NotAuthorizedException;
 
-/**
- * The AbstractCommandsController class is the abstract base class encapsulating common
- * functionality across all Management Controller classes that expose REST API web service endpoints
- * (URLs/URIs) for GemFire shell (Gfsh) commands.
- *
- * @see MemberMXBean
- * @see Gfsh
- * @see ResponseEntity
- * @see org.springframework.stereotype.Controller
- * @see ExceptionHandler
- * @see InitBinder
- * @see org.springframework.web.bind.annotation.ResponseBody
- * @since GemFire 8.0
- */
-@SuppressWarnings("unused")
-public abstract class AbstractAdminRestController {
-  protected static final String REST_API_VERSION = "/v1";
+public class AbstractManagementController implements ServletContextAware {
+
+  protected static final String MANAGEMENT_API_VERSION = "/v2";
+  protected SecurityService securityService;
+  protected LocatorClusterManagementService clusterManagementService;
+
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+    clusterManagementService = (LocatorClusterManagementService) servletContext
+        .getAttribute(JettyHelper.CLUSTER_MANAGEMENT_SERVICE_CONTEXT_PARAM);
+  }
+
   private static final Logger logger = LogService.getLogger();
 
   @ExceptionHandler(Exception.class)
-  public ResponseEntity<String> internalError(final Exception e) {
-    final String stackTrace = getPrintableStackTrace(e);
-    logger.fatal(stackTrace);
-    return new ResponseEntity<>(stackTrace, HttpStatus.INTERNAL_SERVER_ERROR);
+  public ResponseEntity<ClusterManagementResult> internalError(final Exception e) {
+    logger.error(e.getMessage(), e);
+    return new ResponseEntity<>(new ClusterManagementResult(false, e.getMessage()),
+        HttpStatus.INTERNAL_SERVER_ERROR);
   }
 
   @ExceptionHandler(AuthenticationFailedException.class)
-  public ResponseEntity<String> unauthorized(AuthenticationFailedException e) {
-    return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED);
+  public ResponseEntity<ClusterManagementResult> unauthorized(AuthenticationFailedException e) {
+    return new ResponseEntity<>(new ClusterManagementResult(false, e.getMessage()),
+        HttpStatus.UNAUTHORIZED);
   }
 
   @ExceptionHandler({NotAuthorizedException.class, SecurityException.class})
-  public ResponseEntity<String> forbidden(Exception e) {
-    return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
+  public ResponseEntity<ClusterManagementResult> forbidden(Exception e) {
+    logger.info(e.getMessage());
+    return new ResponseEntity<>(new ClusterManagementResult(false, e.getMessage()),
+        HttpStatus.FORBIDDEN);
   }
 
   @ExceptionHandler(MalformedObjectNameException.class)
-  public ResponseEntity<String> badRequest(final MalformedObjectNameException e) {
-    logger.info(e);
-    return new ResponseEntity<>(getPrintableStackTrace(e), HttpStatus.BAD_REQUEST);
+  public ResponseEntity<ClusterManagementResult> badRequest(final MalformedObjectNameException e) {
+    logger.info(e.getMessage(), e);
+    return new ResponseEntity<>(new ClusterManagementResult(false, e.getMessage()),
+        HttpStatus.BAD_REQUEST);
   }
 
   @ExceptionHandler(InstanceNotFoundException.class)
-  public ResponseEntity<String> notFound(final InstanceNotFoundException e) {
-    logger.info(e);
-    return new ResponseEntity<>(getPrintableStackTrace(e), HttpStatus.NOT_FOUND);
+  public ResponseEntity<ClusterManagementResult> notFound(final InstanceNotFoundException e) {
+    logger.info(e.getMessage(), e);
+    return new ResponseEntity<>(new ClusterManagementResult(false, e.getMessage()),
+        HttpStatus.NOT_FOUND);
   }
 
   /**
@@ -92,23 +96,11 @@ public abstract class AbstractAdminRestController {
    * @return a ResponseEntity with an appropriate HTTP status code (403 - Forbidden)
    */
   @ExceptionHandler(AccessDeniedException.class)
-  public ResponseEntity<String> handleException(final AccessDeniedException cause) {
-    logger.info(cause);
-    return new ResponseEntity<>(cause.getMessage(), HttpStatus.FORBIDDEN);
-  }
-
-  /**
-   * Writes the stack trace of the Throwable to a String.
-   *
-   * @param t a Throwable object who's stack trace will be written to a String.
-   * @return a String containing the stack trace of the Throwable.
-   * @see StringWriter
-   * @see Throwable#printStackTrace(PrintWriter)
-   */
-  private static String getPrintableStackTrace(final Throwable t) {
-    final StringWriter stackTraceWriter = new StringWriter();
-    t.printStackTrace(new PrintWriter(stackTraceWriter));
-    return stackTraceWriter.toString();
+  public ResponseEntity<ClusterManagementResult> handleException(
+      final AccessDeniedException cause) {
+    logger.info(cause.getMessage(), cause);
+    return new ResponseEntity<>(new ClusterManagementResult(false, cause.getMessage()),
+        HttpStatus.FORBIDDEN);
   }
 
   /**
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/RegionManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
similarity index 72%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/RegionManagementController.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
index 9f016e8..d6bc916 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/RegionManagementController.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
@@ -13,9 +13,9 @@
  * the License.
  */
 
-package org.apache.geode.management.internal.web.controllers;
+package org.apache.geode.management.internal.rest.controllers;
 
-import static org.apache.geode.management.internal.web.controllers.AbstractManagementController.MANAGEMENT_API_VERSION;
+import static org.apache.geode.management.internal.rest.controllers.AbstractManagementController.MANAGEMENT_API_VERSION;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 
 import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.internal.api.ClusterManagementResult;
 
 @Controller("regionManagement")
 @RequestMapping(MANAGEMENT_API_VERSION)
@@ -33,8 +34,11 @@ public class RegionManagementController extends AbstractManagementController {
 
   @PreAuthorize("@securityService.authorize('DATA', 'MANAGE')")
   @RequestMapping(method = RequestMethod.POST, value = "/regions")
-  public ResponseEntity<String> createRegion(@RequestBody RegionConfig regionConfig) {
-    return new ResponseEntity(regionConfig.getName(), HttpStatus.CREATED);
+  public ResponseEntity<ClusterManagementResult> createRegion(
+      @RequestBody RegionConfig regionConfig) {
+    ClusterManagementResult result =
+        clusterManagementService.create(regionConfig);
+    return new ResponseEntity<>(result,
+        result.isSuccessful() ? HttpStatus.CREATED : HttpStatus.INTERNAL_SERVER_ERROR);
   }
-
 }
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/converter/CustomMappingJackson2HttpMessageConverter.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/converter/CustomMappingJackson2HttpMessageConverter.java
similarity index 98%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/converter/CustomMappingJackson2HttpMessageConverter.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/converter/CustomMappingJackson2HttpMessageConverter.java
index 2d4dc01..4ecb908 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/converter/CustomMappingJackson2HttpMessageConverter.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/converter/CustomMappingJackson2HttpMessageConverter.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.web.converter;
+package org.apache.geode.management.internal.rest.converter;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/GeodeAuthenticationProvider.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/GeodeAuthenticationProvider.java
similarity index 98%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/GeodeAuthenticationProvider.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/GeodeAuthenticationProvider.java
index 1d8ef56..4ec684e 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/GeodeAuthenticationProvider.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/GeodeAuthenticationProvider.java
@@ -13,7 +13,7 @@
  * the License.
  */
 
-package org.apache.geode.management.internal.web.security;
+package org.apache.geode.management.internal.rest.security;
 
 import java.util.Properties;
 
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityConfiguration.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
similarity index 90%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityConfiguration.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
index 106741c..6d28733 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityConfiguration.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityConfiguration.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.web.security;
+package org.apache.geode.management.internal.rest.security;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
@@ -29,7 +29,9 @@ import org.springframework.security.config.http.SessionCreationPolicy;
 @Configuration
 @EnableWebSecurity
 @EnableGlobalMethodSecurity(prePostEnabled = true)
-@ComponentScan("org.apache.geode.management.internal.web")
+// this package name needs to be different than the admin rest controller's package name
+// otherwise this component scan will pick up the admin rest controllers as well.
+@ComponentScan("org.apache.geode.management.internal.rest")
 public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter {
 
   @Autowired
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityService.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityService.java
similarity index 98%
rename from geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityService.java
rename to geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityService.java
index 4259f7f..f0fd792 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityService.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/security/RestSecurityService.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.management.internal.web.security;
+package org.apache.geode.management.internal.rest.security;
 
 import javax.servlet.ServletContext;
 
diff --git a/geode-web-management/src/main/webapp/WEB-INF/geode-management-servlet.xml b/geode-web-management/src/main/webapp/WEB-INF/geode-management-servlet.xml
index f0d54fe..22cae8e 100644
--- a/geode-web-management/src/main/webapp/WEB-INF/geode-management-servlet.xml
+++ b/geode-web-management/src/main/webapp/WEB-INF/geode-management-servlet.xml
@@ -36,7 +36,8 @@
       <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
       <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
       <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
-      <bean class="org.apache.geode.management.internal.web.converter.CustomMappingJackson2HttpMessageConverter" p:objectMapper-ref="objectMapper"/>
+      <bean class="org.apache.geode.management.internal.rest.converter.CustomMappingJackson2HttpMessageConverter"
+            p:objectMapper-ref="objectMapper"/>
     </mvc:message-converters>
   </mvc:annotation-driven>
 
@@ -74,5 +75,5 @@
     </property>
   </bean>
 
-  <bean class="org.apache.geode.management.internal.web.security.RestSecurityConfiguration" />
+  <bean class="org.apache.geode.management.internal.rest.security.RestSecurityConfiguration"/>
 </beans>