You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by GitBox <gi...@apache.org> on 2019/01/15 17:57:46 UTC

[geode] Diff for: [GitHub] jinmeiliao merged pull request #3066: GEODE-6174: Added rest controller to process post request to /geode-m…

diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index 33da4a219b7..b3bd90ec97e 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -140,6 +140,7 @@ dependencies {
   archives project(':geode-protobuf-messages')
   archives project(':geode-web')
   archives project(':geode-web-api')
+  archives project(':geode-web-management')
   archives project(':geode-wan')
   archives project(':geode-cq')
   archives project(':geode-rebalancer')
@@ -463,6 +464,9 @@ distributions {
         from (project(':geode-web-api').configurations.archives.allArtifacts.files) {
           exclude '*.jar'
         }
+        from (project(':geode-web-management').configurations.archives.allArtifacts.files) {
+          exclude '*.jar'
+        }
       }
 
       into('tools/ClientProtocol') {
diff --git a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/GeodeDevRestClient.java b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/GeodeDevRestClient.java
index 2369460985e..5bb9b245222 100644
--- a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/GeodeDevRestClient.java
+++ b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/test/junit/rules/GeodeDevRestClient.java
@@ -52,20 +52,23 @@
 public class GeodeDevRestClient {
   public static final String CONTEXT = "/geode/v1";
 
+  private String context;
   private String bindAddress;
   private int restPort;
   private boolean useSsl;
   private HttpHost host;
 
-  public GeodeDevRestClient(int restPort) {
-    this("localhost", restPort, false);
-  }
 
   public GeodeDevRestClient(String bindAddress, int restPort) {
-    this(bindAddress, restPort, false);
+    this(CONTEXT, bindAddress, restPort, false);
   }
 
   public GeodeDevRestClient(String bindAddress, int restPort, boolean useSsl) {
+    this(CONTEXT, bindAddress, restPort, useSsl);
+  }
+
+  public GeodeDevRestClient(String context, String bindAddress, int restPort, boolean useSsl) {
+    this.context = context;
     this.bindAddress = bindAddress;
     this.restPort = restPort;
     this.useSsl = useSsl;
@@ -73,31 +76,31 @@ public GeodeDevRestClient(String bindAddress, int restPort, boolean useSsl) {
   }
 
   public HttpResponse doHEAD(String query, String username, String password) {
-    HttpHead httpHead = new HttpHead(CONTEXT + query);
+    HttpHead httpHead = new HttpHead(context + query);
     return doRequest(httpHead, username, password);
   }
 
   public HttpResponse doPost(String query, String username, String password, String body) {
-    HttpPost httpPost = new HttpPost(CONTEXT + query);
+    HttpPost httpPost = new HttpPost(context + query);
     httpPost.addHeader("content-type", "application/json");
     httpPost.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
     return doRequest(httpPost, username, password);
   }
 
   public HttpResponse doPut(String query, String username, String password, String body) {
-    HttpPut httpPut = new HttpPut(CONTEXT + query);
+    HttpPut httpPut = new HttpPut(context + query);
     httpPut.addHeader("content-type", "application/json");
     httpPut.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
     return doRequest(httpPut, username, password);
   }
 
   public HttpResponse doGet(String uri, String username, String password) {
-    HttpGet getRequest = new HttpGet(CONTEXT + uri);
+    HttpGet getRequest = new HttpGet(context + uri);
     return doRequest(getRequest, username, password);
   }
 
   public HttpResponse doDelete(String uri, String username, String password) {
-    HttpDelete httpDelete = new HttpDelete(CONTEXT + uri);
+    HttpDelete httpDelete = new HttpDelete(context + uri);
     return doRequest(httpDelete, username, password);
   }
 
@@ -118,6 +121,11 @@ public HttpResponseAssert doPostAndAssert(String uri, String body) {
     return new HttpResponseAssert("Post " + uri, doPost(uri, null, null, body));
   }
 
+  public HttpResponseAssert doPostAndAssert(String uri, String body, String username,
+      String password) {
+    return new HttpResponseAssert("Post " + uri, doPost(uri, username, password, body));
+  }
+
   public HttpResponseAssert doDeleteAndAssert(String uri) {
     return new HttpResponseAssert("Delete " + uri, doDelete(uri, null, null));
   }
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
new file mode 100644
index 00000000000..b7ad6090e61
--- /dev/null
+++ b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+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.test.junit.rules.GeodeDevRestClient;
+import org.apache.geode.test.junit.rules.LocatorStarterRule;
+import org.apache.geode.test.junit.rules.RequiresGeodeHome;
+
+public class RegionManagementIntegrationTest {
+
+  @ClassRule
+  public static LocatorStarterRule locator =
+      new LocatorStarterRule().withHttpService().withAutoStart();
+
+  @ClassRule
+  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
+
+  public static GeodeDevRestClient restClient;
+
+  @BeforeClass
+  public static void setUpClass() throws Exception {
+    restClient =
+        new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false);
+  }
+
+  @Test
+  public void sanityCheck() throws Exception {
+    RegionConfig regionConfig = new RegionConfig();
+    regionConfig.setName("customers");
+    regionConfig.setRefid("REPLICATE");
+
+    ObjectMapper mapper = new ObjectMapper();
+    String json = mapper.writeValueAsString(regionConfig);
+
+    restClient.doPostAndAssert("/regions", json, null, null)
+        .hasStatusCode(201)
+        .hasResponseBody().isEqualTo("customers");
+  }
+}
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
new file mode 100644
index 00000000000..6351faaac82
--- /dev/null
+++ b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.security.SimpleTestSecurityManager;
+import org.apache.geode.test.junit.rules.GeodeDevRestClient;
+import org.apache.geode.test.junit.rules.LocatorStarterRule;
+import org.apache.geode.test.junit.rules.RequiresGeodeHome;
+
+public class RegionManagementSecurityIntegrationTest {
+
+  @ClassRule
+  public static LocatorStarterRule locator = new LocatorStarterRule().withHttpService()
+      .withSecurityManager(SimpleTestSecurityManager.class).withAutoStart();
+
+  @ClassRule
+  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
+
+  public static GeodeDevRestClient restClient;
+
+  @BeforeClass
+  public static void setUpClass() {
+    restClient =
+        new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false);
+  }
+
+  private RegionConfig regionConfig;
+  private String json;
+
+  @Before
+  public void before() throws JsonProcessingException {
+    regionConfig = new RegionConfig();
+    regionConfig.setName("customers");
+    regionConfig.setRefid("REPLICATE");
+    ObjectMapper mapper = new ObjectMapper();
+    json = mapper.writeValueAsString(regionConfig);
+  }
+
+  @Test
+  public void sanityCheck_not_authorized() throws Exception {
+    restClient.doPostAndAssert("/regions", json, "test", "test")
+        .hasStatusCode(403)
+        .hasResponseBody().isEqualTo("Access is denied");
+  }
+
+  @Test
+  public void sanityCheckWithNoCredentials() throws Exception {
+    restClient.doPostAndAssert("/regions", json, null, null)
+        .hasStatusCode(401);
+  }
+
+  @Test
+  public void sanityCheckWithWrongCredentials() throws Exception {
+    restClient.doPostAndAssert("/regions", json, "test", "invalid_pswd")
+        .hasStatusCode(401);
+  }
+
+  @Test
+  public void sanityCheck_success() throws Exception {
+    restClient.doPostAndAssert("/regions", json, "dataManage", "dataManage")
+        .hasStatusCode(201)
+        .hasResponseBody().isEqualTo("customers");
+  }
+
+}
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 7501b75b5d1..ef6ed79b0ee 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -956,6 +956,7 @@ lib/spring-web-4.3.20.RELEASE.jar
 tools/ClientProtocol/geode-protobuf-messages-definitions-0.0.0.zip
 tools/Extensions/geode-web-0.0.0.war
 tools/Extensions/geode-web-api-0.0.0.war
+tools/Extensions/geode-web-management-0.0.0.war
 tools/Modules/Apache_Geode_Modules-0.0.0-AppServer.zip
 tools/Modules/Apache_Geode_Modules-0.0.0-Tomcat.zip
 tools/Modules/Apache_Geode_Modules-0.0.0-tcServer.zip
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/AgentUtil.java b/geode-core/src/main/java/org/apache/geode/management/internal/AgentUtil.java
index 8b22f7d71f7..24f280131a5 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/AgentUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/AgentUtil.java
@@ -130,13 +130,9 @@ private String lookupWarLocationFromClasspath(String versionedWarFileName,
         .findFirst().orElse(null);
   }
 
-  boolean isWebApplicationAvailable(final String warFileLocation) {
-    return StringUtils.isNotBlank(warFileLocation);
-  }
-
-  boolean isWebApplicationAvailable(final String... warFileLocations) {
+  boolean isAnyWarFileAvailable(final String... warFileLocations) {
     for (String warFileLocation : warFileLocations) {
-      if (isWebApplicationAvailable(warFileLocation)) {
+      if (StringUtils.isNotBlank(warFileLocation)) {
         return true;
       }
     }
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 ddd60a9556b..b37c1d5ef8e 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
@@ -215,7 +215,16 @@ private void startHttpService(boolean isServer) {
       if (gemfireWar == null) {
         if (logger.isDebugEnabled()) {
           logger.debug(
-              "Unable to find GemFire Management REST API WAR file; the Management REST Interface for GemFire will not be accessible.");
+              "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.");
         }
       }
 
@@ -248,7 +257,8 @@ private void startHttpService(boolean isServer) {
       }
 
       try {
-        if (agentUtil.isWebApplicationAvailable(gemfireWar, pulseWar, gemfireAPIWar)) {
+        if (agentUtil.isAnyWarFileAvailable(gemfireWar, gemfireManagementWar, pulseWar,
+            gemfireAPIWar)) {
 
           final String bindAddress = this.config.getHttpServiceBindAddress();
           final int port = this.config.getHttpServicePort();
@@ -258,20 +268,25 @@ private void startHttpService(boolean isServer) {
           this.httpServer = JettyHelper.initJetty(bindAddress, port, SSLConfigurationFactory
               .getSSLConfigForComponent(config, SecurableCommunicationChannel.WEB));
 
-          if (agentUtil.isWebApplicationAvailable(gemfireWar)) {
+          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);
           }
 
-          if (agentUtil.isWebApplicationAvailable(pulseWar)) {
+          if (agentUtil.isAnyWarFileAvailable(gemfireManagementWar)) {
+            this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode-management",
+                gemfireManagementWar, securityService, null);
+          }
+
+          if (agentUtil.isAnyWarFileAvailable(pulseWar)) {
             this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/pulse", pulseWar,
                 securityService, createSslProps());
           }
 
           if (isServer && this.config.getStartDevRestApi()) {
-            if (agentUtil.isWebApplicationAvailable(gemfireAPIWar)) {
+            if (agentUtil.isAnyWarFileAvailable(gemfireAPIWar)) {
               this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/geode",
                   gemfireAPIWar, securityService, null);
               this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire-api",
@@ -307,7 +322,7 @@ private void startHttpService(boolean isServer) {
 
           // now, that Tomcat has been started, we can set the URL used by web
           // clients to connect to Pulse
-          if (agentUtil.isWebApplicationAvailable(pulseWar)) {
+          if (agentUtil.isAnyWarFileAvailable(pulseWar)) {
             managerBean.setPulseURL("http://".concat(getHost(bindAddress)).concat(":")
                 .concat(String.valueOf(port)).concat("/pulse/"));
           }
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 fa0f25ca576..6405c52b94f 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
@@ -130,7 +130,7 @@ public void startHttpService() {
       if (isRunningInTomcat()) {
         logger.warn(
             "Detected presence of catalina system properties. HTTP service will not be started. To enable the GemFire Developer REST API, please deploy the /geode-web-api WAR file in your application server.");
-      } else if (agentUtil.isWebApplicationAvailable(gemfireAPIWar)) {
+      } else if (agentUtil.isAnyWarFileAvailable(gemfireAPIWar)) {
 
         final int port = this.config.getHttpServicePort();
 
diff --git a/geode-web-api/src/integrationTest/java/org/apache/geode/rest/internal/web/controllers/RestAccessControllerTest.java b/geode-web-api/src/integrationTest/java/org/apache/geode/rest/internal/web/controllers/RestAccessControllerTest.java
index f8df307fc78..ec177bf60f3 100644
--- a/geode-web-api/src/integrationTest/java/org/apache/geode/rest/internal/web/controllers/RestAccessControllerTest.java
+++ b/geode-web-api/src/integrationTest/java/org/apache/geode/rest/internal/web/controllers/RestAccessControllerTest.java
@@ -49,12 +49,15 @@
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.GenericXmlWebContextLoader;
 import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.context.web.WebMergedContextConfiguration;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.request.RequestPostProcessor;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.GenericWebApplicationContext;
 
 import org.apache.geode.cache.CacheLoader;
 import org.apache.geode.cache.CacheWriter;
@@ -67,11 +70,13 @@
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.TimeoutException;
 import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.management.internal.JettyHelper;
 import org.apache.geode.management.internal.RestAgent;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-servlet.xml"})
+@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-servlet.xml"},
+    loader = TestContextLoader.class)
 @WebAppConfiguration
 public class RestAccessControllerTest {
 
@@ -135,8 +140,7 @@ private static void loadResource(String name) throws Exception {
 
   @Before
   public void setup() {
-    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
-        .build();
+    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
 
     rule.getCache().getRegion("customers").clear();
     rule.getCache().getRegion("orders").clear();
@@ -923,5 +927,16 @@ public void beforeRegionClear(RegionEvent event) throws CacheWriterException {
       // nothing
     }
   }
+}
+
+
+class TestContextLoader extends GenericXmlWebContextLoader {
+  @Override
+  protected void loadBeanDefinitions(GenericWebApplicationContext context,
+      WebMergedContextConfiguration webMergedConfig) {
+    super.loadBeanDefinitions(context, webMergedConfig);
+    context.getServletContext().setAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
+        RestAccessControllerTest.rule.getCache().getSecurityService());
+  }
 
 }
diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/GeodeAuthenticationProvider.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/GeodeAuthenticationProvider.java
index 1f028183958..db5bf5cf2d7 100644
--- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/GeodeAuthenticationProvider.java
+++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/GeodeAuthenticationProvider.java
@@ -18,6 +18,8 @@
 
 import java.util.Properties;
 
+import javax.servlet.ServletContext;
+
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -25,33 +27,18 @@
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.ServletContextAware;
 
-import org.apache.geode.internal.cache.GemFireCacheImpl;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.security.SecurityService;
-import org.apache.geode.internal.security.SecurityServiceFactory;
+import org.apache.geode.management.internal.JettyHelper;
 import org.apache.geode.management.internal.security.ResourceConstants;
 import org.apache.geode.security.GemFireSecurityException;
 
 
 @Component
-public class GeodeAuthenticationProvider implements AuthenticationProvider {
-
-  private final SecurityService securityService;
+public class GeodeAuthenticationProvider implements AuthenticationProvider, ServletContextAware {
 
-  public GeodeAuthenticationProvider() {
-    // TODO: can we pass SecurityService in?
-    this.securityService = findSecurityService();
-  }
-
-  private static SecurityService findSecurityService() {
-    InternalCache cache = GemFireCacheImpl.getInstance();
-    if (cache != null) {
-      return cache.getSecurityService();
-    } else {
-      return SecurityServiceFactory.create();
-    }
-  }
+  private SecurityService securityService;
 
   public SecurityService getSecurityService() {
     return this.securityService;
@@ -80,4 +67,10 @@ public Authentication authenticate(Authentication authentication) throws Authent
   public boolean supports(Class<?> authentication) {
     return authentication.isAssignableFrom(UsernamePasswordAuthenticationToken.class);
   }
+
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  }
 }
diff --git a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityService.java b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityService.java
index b3fe666b7d2..4020ddc3639 100644
--- a/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityService.java
+++ b/geode-web-api/src/main/java/org/apache/geode/rest/internal/web/security/RestSecurityService.java
@@ -14,30 +14,22 @@
  */
 package org.apache.geode.rest.internal.web.security;
 
+import javax.servlet.ServletContext;
+
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.ServletContextAware;
 
-import org.apache.geode.internal.cache.GemFireCacheImpl;
-import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.security.SecurityService;
-import org.apache.geode.internal.security.SecurityServiceFactory;
+import org.apache.geode.management.internal.JettyHelper;
 import org.apache.geode.security.GemFireSecurityException;
 import org.apache.geode.security.ResourcePermission;
 import org.apache.geode.security.ResourcePermission.Operation;
 import org.apache.geode.security.ResourcePermission.Resource;
 
 @Component("securityService")
-public class RestSecurityService {
+public class RestSecurityService implements ServletContextAware {
 
-  private final SecurityService securityService;
-
-  public RestSecurityService() {
-    InternalCache cache = GemFireCacheImpl.getInstance();
-    if (cache != null) {
-      this.securityService = cache.getSecurityService();
-    } else {
-      this.securityService = SecurityServiceFactory.create();
-    }
-  }
+  private SecurityService securityService;
 
   public boolean authorize(String resource, String operation) {
     return authorize(resource, operation, null, null);
@@ -83,4 +75,9 @@ public Object postProcess(String regionPath, Object key, Object value,
     return securityService.postProcess(regionPath, key, value, valueIsSerialized);
   }
 
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  }
 }
diff --git a/geode-web-management/build.gradle b/geode-web-management/build.gradle
new file mode 100644
index 00000000000..3b55c61b6b9
--- /dev/null
+++ b/geode-web-management/build.gradle
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'war'
+
+apply from: "${project.projectDir}/../gradle/geode-dependency-management.gradle"
+apply from: "${project.projectDir}/../gradle/publish.gradle"
+
+
+dependencies {
+
+  compileOnly(project(':geode-core'))
+
+  compileOnly('javax.servlet:javax.servlet-api')
+
+  compile('org.apache.commons:commons-lang3')
+  compile('commons-fileupload:commons-fileupload') {
+    exclude module: 'commons-io'
+  }
+  compile('com.fasterxml.jackson.core:jackson-annotations')
+  compile('com.fasterxml.jackson.core:jackson-core')
+  compile('com.fasterxml.jackson.core:jackson-databind')
+  compile('com.fasterxml.jackson.module:jackson-module-scala_2.10')
+  compile('io.springfox:springfox-swagger2') {
+    exclude module: 'slf4j-api'
+  }
+  compile('io.springfox:springfox-swagger-ui') {
+    exclude module: 'slf4j-api'
+  }
+  compile('org.springframework:spring-beans')
+  compile('org.springframework.security:spring-security-core')
+  compile('org.springframework.security:spring-security-web')
+  compile('org.springframework.security:spring-security-config')
+  compile('org.springframework:spring-web')
+  compile('org.springframework:spring-webmvc')
+  compile('org.springframework.hateoas:spring-hateoas') {
+    exclude module: 'aopalliance'
+    exclude module: 'commons-logging'
+    exclude module: 'objenesis'
+    exclude module: 'slf4j-api'
+    exclude module: 'spring-core'
+  }
+  compile('org.springframework:spring-aspects') {
+    exclude module: 'aopalliance'
+    exclude module: 'aspectjweaver'
+  }
+  compile('org.springframework:spring-oxm') {
+    exclude module: 'commons-logging'
+    exclude module: 'spring-core'
+    exclude module: 'spring-beans'
+  }
+
+
+  testCompile(project(':geode-junit')) {
+    exclude module: 'geode-core'
+  }
+  testCompile(project(':geode-core'))
+  testCompile('javax.servlet:javax.servlet-api')
+
+  integrationTestCompile('org.springframework:spring-test')
+  integrationTestCompile('org.springframework.security:spring-security-test')
+
+  integrationTestCompile(project(':geode-junit')) {
+    exclude module: 'geode-core'
+  }
+  integrationTestCompile(project(':geode-dunit')) {
+    exclude module: 'geode-core'
+  }
+}
+
+sourceSets {
+  integrationTest {
+    resources {
+      srcDir "${projectDir}/src/main/webapp"
+    }
+  }
+}
+
+war {
+  rootSpec.exclude("**/*commons-logging-*.jar")
+  duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+  // this shouldn't be necessary but if it's not specified we're missing some of the jars
+  // from the runtime classpath
+  classpath configurations.runtimeClasspath
+}
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/web/controllers/AbstractAdminRestController.java
new file mode 100644
index 00000000000..fa37da7b0c5
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractAdminRestController.java
@@ -0,0 +1,126 @@
+/*
+ * 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.web.controllers;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MalformedObjectNameException;
+
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+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.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.MemberMXBean;
+import org.apache.geode.management.internal.cli.shell.Gfsh;
+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";
+  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);
+  }
+
+  @ExceptionHandler(AuthenticationFailedException.class)
+  public ResponseEntity<String> unauthorized(AuthenticationFailedException e) {
+    return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED);
+  }
+
+  @ExceptionHandler({NotAuthorizedException.class, SecurityException.class})
+  public ResponseEntity<String> forbidden(Exception e) {
+    return new ResponseEntity<>(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);
+  }
+
+  @ExceptionHandler(InstanceNotFoundException.class)
+  public ResponseEntity<String> notFound(final InstanceNotFoundException e) {
+    logger.info(e);
+    return new ResponseEntity<>(getPrintableStackTrace(e), HttpStatus.NOT_FOUND);
+  }
+
+  /**
+   * Handles an AccessDenied Exception thrown by a REST API web service endpoint, HTTP request
+   * handler method.
+   * <p/>
+   *
+   * @param cause the Exception causing the error.
+   * @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();
+  }
+
+  /**
+   * Initializes data bindings for various HTTP request handler method parameter Java class types.
+   *
+   * @param dataBinder the DataBinder implementation used for Web transactions.
+   * @see WebDataBinder
+   * @see InitBinder
+   */
+  @InitBinder
+  public void initBinder(final WebDataBinder dataBinder) {
+    dataBinder.registerCustomEditor(String[].class,
+        new StringArrayPropertyEditor(StringArrayPropertyEditor.DEFAULT_SEPARATOR, false));
+  }
+}
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java
new file mode 100644
index 00000000000..9fbb1c789e2
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/AbstractManagementController.java
@@ -0,0 +1,36 @@
+/*
+ * 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.web.controllers;
+
+import javax.servlet.ServletContext;
+
+import org.springframework.web.context.ServletContextAware;
+
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.management.internal.JettyHelper;
+
+public class AbstractManagementController extends AbstractAdminRestController implements
+    ServletContextAware {
+
+  protected static final String MANAGEMENT_API_VERSION = "/v2";
+  protected SecurityService securityService;
+
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  }
+}
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/web/controllers/RegionManagementController.java
new file mode 100644
index 00000000000..9f016e8d072
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/controllers/RegionManagementController.java
@@ -0,0 +1,40 @@
+/*
+ * 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.web.controllers;
+
+import static org.apache.geode.management.internal.web.controllers.AbstractManagementController.MANAGEMENT_API_VERSION;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import org.apache.geode.cache.configuration.RegionConfig;
+
+@Controller("regionManagement")
+@RequestMapping(MANAGEMENT_API_VERSION)
+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);
+  }
+
+}
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/web/converter/CustomMappingJackson2HttpMessageConverter.java
new file mode 100644
index 00000000000..2d4dc0113db
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/converter/CustomMappingJackson2HttpMessageConverter.java
@@ -0,0 +1,149 @@
+/*
+ * 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.web.converter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.util.Assert;
+
+/**
+ * The CustomMappingJackson2HttpMessageConverter class...
+ *
+ * @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
+ * @since GemFire 0.0.1
+ */
+@SuppressWarnings("unused")
+public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+  protected static final int INITIAL_BYTE_ARRAY_BUFFER_SIZE = 8192;
+
+  @Override
+  protected void writeInternal(final Object object, final HttpOutputMessage outputMessage)
+      throws IOException, HttpMessageNotWritableException {
+    HttpOutputMessageWrapper outputMessageWrapper =
+        new BufferingHttpOutputMessageWrapper(outputMessage);
+    super.writeInternal(object, outputMessageWrapper);
+    outputMessageWrapper.flush();
+  }
+
+  protected static class BufferingHttpOutputMessageWrapper implements HttpOutputMessageWrapper {
+
+    private final ByteArrayOutputStream outputStream;
+
+    private final HttpOutputMessage httpOutputMessage;
+
+    protected BufferingHttpOutputMessageWrapper(final HttpOutputMessage httpOutputMessage) {
+      Assert.notNull(httpOutputMessage, "The HttpOutputMessage instance to wrap must not be null!");
+      this.httpOutputMessage = httpOutputMessage;
+      this.outputStream = new ByteArrayOutputStream(INITIAL_BYTE_ARRAY_BUFFER_SIZE);
+    }
+
+    @Override
+    public OutputStream getBody() throws IOException {
+      return outputStream;
+    }
+
+    public long getContentLength() {
+      return outputStream.size();
+    }
+
+    @Override
+    public HttpHeaders getHeaders() {
+      return httpOutputMessage.getHeaders();
+    }
+
+    public void flush() throws IOException {
+      getHeaders().setContentLength(getContentLength());
+      outputStream.writeTo(httpOutputMessage.getBody());
+      outputStream.reset();
+    }
+  }
+
+  /**
+   * While sound idea in theory to "count the bytes as you stream/write", thus preserving memory,
+   * this does not work in practice since the HTTP headers must be written to the HTTP output stream
+   * response before the body!
+   */
+  protected static class ContentLengthAccessibleHttpOutputMessageWrapper
+      implements HttpOutputMessageWrapper {
+
+    private final ByteCountingOutputStream outputStream;
+
+    private final HttpOutputMessage httpOutputMessage;
+
+    protected ContentLengthAccessibleHttpOutputMessageWrapper(
+        final HttpOutputMessage httpOutputMessage) throws IOException {
+      Assert.notNull(httpOutputMessage, "The HttpOutputMessage instance to wrap must not be null!");
+      this.httpOutputMessage = httpOutputMessage;
+      this.outputStream = new ByteCountingOutputStream(this.httpOutputMessage.getBody());
+    }
+
+    @Override
+    public OutputStream getBody() throws IOException {
+      return outputStream;
+    }
+
+    public long getContentLength() {
+      return outputStream.getByteCount();
+    }
+
+    @Override
+    public HttpHeaders getHeaders() {
+      return httpOutputMessage.getHeaders();
+    }
+
+    public void flush() throws IOException {
+      getHeaders().setContentLength(getContentLength());
+    }
+  }
+
+  protected interface HttpOutputMessageWrapper extends HttpOutputMessage {
+
+    long getContentLength();
+
+    void flush() throws IOException;
+
+  }
+
+  protected static class ByteCountingOutputStream extends OutputStream {
+
+    private AtomicLong byteCount = new AtomicLong(0l);
+
+    private final OutputStream outputStream;
+
+    protected ByteCountingOutputStream(final OutputStream outputStream) {
+      Assert.notNull(outputStream, "The OutputStream to wrap must not be null!");
+      this.outputStream = outputStream;
+    }
+
+    protected long getByteCount() {
+      return byteCount.get();
+    }
+
+    @Override
+    public void write(final int byteData) throws IOException {
+      outputStream.write(byteData);
+      byteCount.incrementAndGet();
+    }
+  }
+
+}
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/web/security/GeodeAuthenticationProvider.java
new file mode 100644
index 00000000000..1d8ef564780
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/GeodeAuthenticationProvider.java
@@ -0,0 +1,76 @@
+/*
+ * 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.web.security;
+
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.ServletContextAware;
+
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.management.internal.JettyHelper;
+import org.apache.geode.management.internal.security.ResourceConstants;
+import org.apache.geode.security.GemFireSecurityException;
+
+
+@Component
+public class GeodeAuthenticationProvider implements AuthenticationProvider, ServletContextAware {
+
+  private SecurityService securityService;
+
+
+  public SecurityService getSecurityService() {
+    return this.securityService;
+  }
+
+  @Override
+  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+    String username = authentication.getName();
+    String password = authentication.getCredentials().toString();
+    Properties credentials = new Properties();
+    if (username != null)
+      credentials.put(ResourceConstants.USER_NAME, username);
+    if (password != null)
+      credentials.put(ResourceConstants.PASSWORD, password);
+
+    try {
+      securityService.login(credentials);
+      return new UsernamePasswordAuthenticationToken(username, password,
+          AuthorityUtils.NO_AUTHORITIES);
+    } catch (GemFireSecurityException e) {
+      throw new BadCredentialsException(e.getLocalizedMessage(), e);
+    }
+  }
+
+  @Override
+  public boolean supports(Class<?> authentication) {
+    return authentication.isAssignableFrom(UsernamePasswordAuthenticationToken.class);
+  }
+
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  }
+}
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/web/security/RestSecurityConfiguration.java
new file mode 100644
index 00000000000..106741c4280
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * 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.web.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@ComponentScan("org.apache.geode.management.internal.web")
+public class RestSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+  @Autowired
+  private GeodeAuthenticationProvider authProvider;
+
+  @Override
+  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+    auth.authenticationProvider(authProvider);
+  }
+
+  @Bean
+  @Override
+  public AuthenticationManager authenticationManagerBean() throws Exception {
+    return super.authenticationManagerBean();
+  }
+
+  protected void configure(HttpSecurity http) throws Exception {
+    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
+        .authorizeRequests()
+        // .antMatchers("/ping", "/docs/**", "/swagger-ui.html", "/v2/api-docs/**",
+        // "/webjars/springfox-swagger-ui/**", "/swagger-resources/**")
+        // .permitAll()
+        .anyRequest().authenticated().and().csrf().disable();
+
+    if (this.authProvider.getSecurityService().isIntegratedSecurity()) {
+      http.httpBasic();
+    } else {
+      http.authorizeRequests().anyRequest().permitAll();
+    }
+  }
+}
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/web/security/RestSecurityService.java
new file mode 100644
index 00000000000..4259f7fe08f
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/web/security/RestSecurityService.java
@@ -0,0 +1,83 @@
+/*
+ * 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.web.security;
+
+import javax.servlet.ServletContext;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.ServletContextAware;
+
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.management.internal.JettyHelper;
+import org.apache.geode.security.GemFireSecurityException;
+import org.apache.geode.security.ResourcePermission;
+import org.apache.geode.security.ResourcePermission.Operation;
+import org.apache.geode.security.ResourcePermission.Resource;
+
+@Component("securityService")
+public class RestSecurityService implements ServletContextAware {
+
+  private SecurityService securityService;
+
+  public boolean authorize(String resource, String operation) {
+    return authorize(resource, operation, null, null);
+  }
+
+  public boolean authorize(String resource, String operation, String region) {
+    return authorize(resource, operation, region, null);
+  }
+
+  /**
+   * this does not need to return a boolean since it's not used in the @PreAuthorize tag
+   */
+  public void authorize(ResourcePermission permission) {
+    securityService.authorize(permission);
+  }
+
+
+  /**
+   * calls used in @PreAuthorize tag needs to return a boolean
+   */
+  public boolean authorize(String resource, String operation, String region, String key) {
+    try {
+      securityService.authorize(Resource.valueOf(resource), Operation.valueOf(operation), region,
+          key);
+      return true;
+    } catch (GemFireSecurityException ex) {
+      return false;
+    }
+  }
+
+  public boolean authorize(String operation, String region, String[] keys) {
+    boolean authorized = false;
+    for (String key : keys) {
+      authorized = authorize("DATA", operation, region, key);
+      if (!authorized)
+        return false;
+    }
+    return true;
+  }
+
+  public Object postProcess(String regionPath, Object key, Object value,
+      boolean valueIsSerialized) {
+    return securityService.postProcess(regionPath, key, value, valueIsSerialized);
+  }
+
+  @Override
+  public void setServletContext(ServletContext servletContext) {
+    securityService = (SecurityService) servletContext
+        .getAttribute(JettyHelper.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM);
+  }
+}
diff --git a/geode-web-management/src/main/webapp/META-INF/NOTICE b/geode-web-management/src/main/webapp/META-INF/NOTICE
new file mode 100644
index 00000000000..d4746dd46dd
--- /dev/null
+++ b/geode-web-management/src/main/webapp/META-INF/NOTICE
@@ -0,0 +1,73 @@
+Apache Geode
+Copyright 2016-2018 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
+The following NOTICEs pertain to software distributed with this project.
+
+stream-lib
+Copyright 2016 AddThis
+
+   This product includes software developed by AddThis.
+
+   This product also includes code adapted from:
+
+   Apache Solr (http://lucene.apache.org/solr/)
+   Copyright 2014 The Apache Software Foundation
+
+This product includes software developed by the MX4J
+project (http://mx4j.sourceforge.net).
+
+Java ClassMate library was originally written by Tatu Saloranta (tatu.saloranta@iki.fi)
+
+  Other developers who have contributed code are:
+  
+  * Brian Langel
+
+Jackson Core
+
+  # Jackson JSON processor
+  
+  Jackson is a high-performance, Free/Open Source JSON processing library.
+  It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
+  been in development since 2007.
+  It is currently developed by a community of developers, as well as supported
+  commercially by FasterXML.com.
+  
+  ## Licensing
+  
+  Jackson core and extension components may licensed under different licenses.
+  To find the details that apply to this artifact see the accompanying LICENSE file.
+  For more information, including possible other licensing options, contact
+  FasterXML.com (http://fasterxml.com).
+  
+  ## Credits
+  
+  A list of contributors may be found from CREDITS file, which is included
+  in some artifacts (usually source distributions); but is always available
+  from the source code management (SCM) system project uses.
+
+Spring Framework
+Copyright (c) 2002-2017 Pivotal, Inc.
+
+  This product is licensed to you under the Apache License, Version 2.0
+  (the "License"). You may not use this product except in compliance with
+  the License.
+  
+  This product may include a number of subcomponents with separate
+  copyright notices and license terms. Your use of the source code for
+  these subcomponents is subject to the terms and conditions of the
+  subcomponent's license, as noted in the license.txt file.
+
+Spring Hateoas
+Copyright (c) [2012-2014] Pivotal Software, Inc.
+
+  This product is licensed to you under the Apache License, Version 2.0 (the "License").  
+  You may not use this product except in compliance with the License.  
+  
+  This product may include a number of subcomponents with
+  separate copyright notices and license terms. Your use of the source
+  code for the these subcomponents is subject to the terms and
+  conditions of the subcomponent's license, as noted in the LICENSE file.
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
new file mode 100644
index 00000000000..f0d54fe3e17
--- /dev/null
+++ b/geode-web-management/src/main/webapp/WEB-INF/geode-management-servlet.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:mvc="http://www.springframework.org/schema/mvc"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context.xsd
+        http://www.springframework.org/schema/mvc
+        http://www.springframework.org/schema/mvc/spring-mvc.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd
+  ">
+  <context:annotation-config />
+
+  <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
+    <mvc:message-converters register-defaults="false">
+      <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"/>
+    </mvc:message-converters>
+  </mvc:annotation-driven>
+
+  <mvc:default-servlet-handler/>
+
+  <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"
+        p:favorPathExtension="true"
+        p:favorParameter="false"
+        p:ignoreAcceptHeader="false"
+        p:useJaf="false"
+        p:defaultContentType="application/json">
+    <property name="mediaTypes">
+      <value>
+        json=application/json
+      </value>
+    </property>
+  </bean>
+  
+  <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
+        p:failOnEmptyBeans="true"
+        p:indentOutput="true"
+        p:simpleDateFormat="MM/dd/yyyy"
+    >
+    <property name="featuresToEnable">
+      <array>
+        <util:constant static-field="com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_COMMENTS"/>
+        <util:constant static-field="com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES"/>
+        <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT"/>
+      </array>
+    </property>
+    <property name="featuresToDisable">
+      <array>
+        <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES"/>
+      </array>
+    </property>
+  </bean>
+
+  <bean class="org.apache.geode.management.internal.web.security.RestSecurityConfiguration" />
+</beans>
diff --git a/geode-web-management/src/main/webapp/WEB-INF/web.xml b/geode-web-management/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..026b0d1101d
--- /dev/null
+++ b/geode-web-management/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+         version="3.0">
+
+  <display-name>Geode Management REST API</display-name>
+
+  <description>
+    Web deployment descriptor declaring the Geode Management API for Geode.
+  </description>
+
+  <filter>
+    <filter-name>springSecurityFilterChain</filter-name>
+    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>springSecurityFilterChain</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <servlet>
+    <description>
+      The Spring DispatcherServlet (FrontController) handling all HTTP requests to the Geode Management REST API.
+    </description>
+    <servlet-name>geode-management</servlet-name>
+    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+    <async-supported>true</async-supported>
+  </servlet>
+   
+  <servlet-mapping>
+    <servlet-name>geode-management</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+</web-app>
diff --git a/geode-web-management/src/test/resources/expected-pom.xml b/geode-web-management/src/test/resources/expected-pom.xml
new file mode 100644
index 00000000000..bc51ae13094
--- /dev/null
+++ b/geode-web-management/src/test/resources/expected-pom.xml
@@ -0,0 +1,877 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  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.
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.geode</groupId>
+  <artifactId>geode-web-api</artifactId>
+  <version>1.9.0-SNAPSHOT</version>
+  <name>Apache Geode</name>
+  <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
+  <url>http://geode.apache.org</url>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+  <scm>
+    <connection>scm:git:https://github.com:apache/geode.git</connection>
+    <developerConnection>scm:git:https://github.com:apache/geode.git</developerConnection>
+    <url>https://github.com/apache/geode</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>commons-io</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-scala_2.10</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger2</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>slf4j-api</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger-ui</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>slf4j-api</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-beans</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-web</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-config</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-web</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-webmvc</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.hateoas</groupId>
+      <artifactId>spring-hateoas</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>slf4j-api</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>objenesis</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>spring-core</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>commons-logging</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>aopalliance</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-aspects</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>aopalliance</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>aspectjweaver</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-oxm</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>spring-beans</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>spring-core</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>commons-logging</artifactId>
+          <groupId>*</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-core</artifactId>
+        <version>2.0.0-beta.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-wan</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.assertj</groupId>
+        <artifactId>assertj-core</artifactId>
+        <version>3.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>mx4j</groupId>
+        <artifactId>mx4j-tools</artifactId>
+        <version>3.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.palantir.docker.compose</groupId>
+        <artifactId>docker-compose-rule-core</artifactId>
+        <version>0.31.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.pholser</groupId>
+        <artifactId>junit-quickcheck-generators</artifactId>
+        <version>0.8.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.lucene</groupId>
+        <artifactId>lucene-core</artifactId>
+        <version>6.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>redis.clients</groupId>
+        <artifactId>jedis</artifactId>
+        <version>2.9.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-chrome-driver</artifactId>
+        <version>3.13.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-core</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.protobuf</groupId>
+        <artifactId>protobuf-java</artifactId>
+        <version>3.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-core</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-configuration</groupId>
+        <artifactId>commons-configuration</artifactId>
+        <version>1.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-old-versions</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-test</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>com.carrotsearch.randomizedtesting</groupId>
+        <artifactId>randomizedtesting-runner</artifactId>
+        <version>2.5.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>27.0-jre</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.cargo</groupId>
+        <artifactId>cargo-core-uberjar</artifactId>
+        <version>1.6.10</version>
+      </dependency>
+      <dependency>
+        <groupId>com.healthmarketscience.rmiio</groupId>
+        <artifactId>rmiio</artifactId>
+        <version>2.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.ejb</groupId>
+        <artifactId>ejb-api</artifactId>
+        <version>3.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.stephenc.findbugs</groupId>
+        <artifactId>findbugs-annotations</artifactId>
+        <version>1.3.9-1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-cq</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.annotation</groupId>
+        <artifactId>jsr250-api</artifactId>
+        <version>1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.xml.bind</groupId>
+        <artifactId>jaxb-api</artifactId>
+        <version>2.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-library</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-experimental-driver</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-web</artifactId>
+        <version>4.2.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-api-mockito2</artifactId>
+        <version>2.0.0-beta.5</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-beanutils</groupId>
+        <artifactId>commons-beanutils</artifactId>
+        <version>1.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.annotation</groupId>
+        <artifactId>javax.annotation-api</artifactId>
+        <version>1.3.2</version>
+      </dependency>
+      <dependency>
+        <groupId>net.sf.jopt-simple</groupId>
+        <artifactId>jopt-simple</artifactId>
+        <version>5.0.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jgroups</groupId>
+        <artifactId>jgroups</artifactId>
+        <version>3.6.14.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-core</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-modeler</groupId>
+        <artifactId>commons-modeler</artifactId>
+        <version>2.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-connectors</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jul</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.shell</groupId>
+        <artifactId>spring-shell</artifactId>
+        <version>1.2.0.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+        <version>3.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-all</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-junit</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.12</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.activation</groupId>
+        <artifactId>javax.activation</artifactId>
+        <version>1.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.springfox</groupId>
+        <artifactId>springfox-swagger-ui</artifactId>
+        <version>2.9.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-rebalancer</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.postgresql</groupId>
+        <artifactId>postgresql</artifactId>
+        <version>42.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>net.java.dev.jna</groupId>
+        <artifactId>jna</artifactId>
+        <version>4.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>it.unimi.dsi</groupId>
+        <artifactId>fastutil</artifactId>
+        <version>8.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>io.springfox</groupId>
+        <artifactId>springfox-swagger2</artifactId>
+        <version>2.9.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.davidmoten</groupId>
+        <artifactId>geo</artifactId>
+        <version>0.7.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-webmvc</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-old-client-support</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-core</artifactId>
+        <version>2.3.2.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore</artifactId>
+        <version>4.4.10</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-scala_2.10</artifactId>
+        <version>2.9.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.lucene</groupId>
+        <artifactId>lucene-test-framework</artifactId>
+        <version>6.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>net.spy</groupId>
+        <artifactId>spymemcached</artifactId>
+        <version>2.12.2</version>
+      </dependency>
+      <dependency>
+        <groupId>mx4j</groupId>
+        <artifactId>mx4j</artifactId>
+        <version>3.0.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>io.github.classgraph</groupId>
+        <artifactId>classgraph</artifactId>
+        <version>4.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>4.5.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jcl</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-lang3</artifactId>
+        <version>3.8.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-beans</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-web-api</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>servlet-api</artifactId>
+        <version>3.0.20100224</version>
+      </dependency>
+      <dependency>
+        <groupId>org.fusesource.jansi</groupId>
+        <artifactId>jansi</artifactId>
+        <version>1.17.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-core</artifactId>
+        <version>2.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-web</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>pl.pragmatists</groupId>
+        <artifactId>JUnitParams</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>javax.servlet-api</artifactId>
+        <version>3.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.xml.bind</groupId>
+        <artifactId>jaxb-impl</artifactId>
+        <version>2.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.bouncycastle</groupId>
+        <artifactId>bcpkix-jdk15on</artifactId>
+        <version>1.60</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.hateoas</groupId>
+        <artifactId>spring-hateoas</artifactId>
+        <version>0.25.0.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-validator</groupId>
+        <artifactId>commons-validator</artifactId>
+        <version>1.6</version>
+      </dependency>
+      <dependency>
+        <groupId>cglib</groupId>
+        <artifactId>cglib</artifactId>
+        <version>3.2.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-pulse</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>com.mockrunner</groupId>
+        <artifactId>mockrunner-servlet</artifactId>
+        <version>1.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-all</artifactId>
+        <version>4.1.31.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.lucene</groupId>
+        <artifactId>lucene-queryparser</artifactId>
+        <version>6.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>1.7.25</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-core</artifactId>
+        <version>4.2.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-test</artifactId>
+        <version>4.2.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-aspects</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.mail</groupId>
+        <artifactId>javax.mail-api</artifactId>
+        <version>1.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.httpunit</groupId>
+        <artifactId>httpunit</artifactId>
+        <version>1.7.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-support</artifactId>
+        <version>3.13.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.jayway.jsonpath</groupId>
+        <artifactId>json-path</artifactId>
+        <version>2.4.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-dunit</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-slf4j-impl</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-config</artifactId>
+        <version>4.2.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-api</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-oxm</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.istack</groupId>
+        <artifactId>istack-commons-runtime</artifactId>
+        <version>2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>apache-geode</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-protobuf-messages</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>com.jayway.jsonpath</groupId>
+        <artifactId>json-path-assert</artifactId>
+        <version>2.4.0</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-logging</groupId>
+        <artifactId>commons-logging</artifactId>
+        <version>1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-common</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-json</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-annotations</artifactId>
+        <version>2.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>mx4j</groupId>
+        <artifactId>mx4j-remote</artifactId>
+        <version>3.0.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-web</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.stefanbirkner</groupId>
+        <artifactId>system-rules</artifactId>
+        <version>1.19.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.persistence</groupId>
+        <artifactId>javax.persistence</artifactId>
+        <version>2.2.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-remote-driver</artifactId>
+        <version>3.13.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.lucene</groupId>
+        <artifactId>lucene-analyzers-phonetic</artifactId>
+        <version>6.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derby</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-ldap</artifactId>
+        <version>4.2.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>mysql</groupId>
+        <artifactId>mysql-connector-java</artifactId>
+        <version>5.1.46</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.lucene</groupId>
+        <artifactId>lucene-analyzers-common</artifactId>
+        <version>6.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-module-junit4</artifactId>
+        <version>2.0.0-beta.5</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-core</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.resource</groupId>
+        <artifactId>javax.resource-api</artifactId>
+        <version>1.7.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-protobuf</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-tx</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-api</artifactId>
+        <version>3.13.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-expression</artifactId>
+        <version>4.3.20.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.iq80.snappy</groupId>
+        <artifactId>snappy</artifactId>
+        <version>0.4</version>
+      </dependency>
+      <dependency>
+        <groupId>com.zaxxer</groupId>
+        <artifactId>HikariCP</artifactId>
+        <version>3.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>antlr</groupId>
+        <artifactId>antlr</artifactId>
+        <version>2.7.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-lucene</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-core</artifactId>
+        <version>1.4.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+        <version>2.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>com.palantir.docker.compose</groupId>
+        <artifactId>docker-compose-rule-junit4</artifactId>
+        <version>0.31.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.awaitility</groupId>
+        <artifactId>awaitility</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>2.23.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.skyscreamer</groupId>
+        <artifactId>jsonassert</artifactId>
+        <version>1.5.0</version>
+      </dependency>
+      <dependency>
+        <groupId>xerces</groupId>
+        <artifactId>xercesImpl</artifactId>
+        <version>2.12.0</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-fileupload</groupId>
+        <artifactId>commons-fileupload</artifactId>
+        <version>1.3.3</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-digester</groupId>
+        <artifactId>commons-digester</artifactId>
+        <version>2.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.pholser</groupId>
+        <artifactId>junit-quickcheck-core</artifactId>
+        <version>0.8.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.bcel</groupId>
+        <artifactId>bcel</artifactId>
+        <version>6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-concurrency-test</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+</project>
diff --git a/gradle/geode-dependency-management.gradle b/gradle/geode-dependency-management.gradle
index c935ee10331..3a27c35181d 100644
--- a/gradle/geode-dependency-management.gradle
+++ b/gradle/geode-dependency-management.gradle
@@ -67,6 +67,7 @@ class GeodeDependencyManagementPlugin implements Plugin<Project> {
           entry('geode-wan')
           entry('geode-web')
           entry('geode-web-api')
+          entry('geode-management-rest-api')
         }
 
         // informal, inter-group dependencySet
diff --git a/settings.gradle b/settings.gradle
index a9acd43a3e9..d584f0cb29d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -30,6 +30,7 @@ include 'geode-dunit'
 include 'geode-core'
 include 'geode-web'
 include 'geode-web-api'
+include 'geode-web-management'
 include 'geode-pulse'
 include 'geode-pulse:geode-pulse-test'
 include 'geode-assembly'


With regards,
Apache Git Services