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

[geode] branch develop updated: GEODE-6811: be able to list gateway receivers using management api (#3669)

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

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


The following commit(s) were added to refs/heads/develop by this push:
     new d97f119  GEODE-6811: be able to list gateway receivers using management api (#3669)
d97f119 is described below

commit d97f1194b34c21e266eb2882a56552106eaa4666
Author: jackw26 <jw...@pivotal.io>
AuthorDate: Mon Jun 10 08:36:48 2019 -0700

    GEODE-6811: be able to list gateway receivers using management api (#3669)
    
    Co-authored-by: Jinmei Liao <ji...@pivotal.io>
    Co-authored-by: Peter Tran <pt...@pivotal.io>
    
    * rename CacheConfig.GatewayReceiver to GatewayReceiverConfig
---
 .../integrationTest/resources/assembly_content.txt |   2 +-
 .../api/LocatorClusterManagementService.java       |   3 +
 .../cli/commands/CreateGatewayReceiverCommand.java |   9 +-
 .../commands/DestroyGatewayReceiverCommand.java    |   3 +-
 .../cli/functions/GatewayReceiverFunctionArgs.java |   4 +-
 .../mutators/GatewayReceiverConfigManager.java     |  57 ++++
 .../sanctioned-geode-management-serializables.txt  |   1 +
 ...nternalConfigurationPersistenceServiceTest.java |   3 +-
 .../geode/internal/config/JAXBServiceTest.java     |   3 +-
 .../geode/cache/configuration/CacheConfig.java     | 247 +----------------
 .../cache/configuration/GatewayReceiverConfig.java | 291 +++++++++++++++++++++
 .../internal/rest/PlainLocatorContextLoader.java   |   4 +
 .../rest/GatewayManagementIntegrationTest.java     | 104 ++++++++
 .../controllers/GatewayManagementController.java   |  47 ++++
 14 files changed, 526 insertions(+), 252 deletions(-)

diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index cfc4924..7304fb4 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -292,7 +292,6 @@ javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewayHub.Gateway.Gate
 javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewayHub.Gateway.GatewayQueue.html
 javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewayHub.Gateway.html
 javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewayHub.html
-javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewayReceiver.html
 javadoc/org/apache/geode/cache/configuration/CacheConfig.GatewaySender.html
 javadoc/org/apache/geode/cache/configuration/CacheConfig.html
 javadoc/org/apache/geode/cache/configuration/CacheElement.html
@@ -306,6 +305,7 @@ javadoc/org/apache/geode/cache/configuration/DynamicRegionFactoryType.html
 javadoc/org/apache/geode/cache/configuration/EnumActionDestroyOverflow.html
 javadoc/org/apache/geode/cache/configuration/EnumReadableWritable.html
 javadoc/org/apache/geode/cache/configuration/FunctionServiceType.html
+javadoc/org/apache/geode/cache/configuration/GatewayReceiverConfig.html
 javadoc/org/apache/geode/cache/configuration/JndiBindingsType.JndiBinding.ConfigProperty.html
 javadoc/org/apache/geode/cache/configuration/JndiBindingsType.JndiBinding.html
 javadoc/org/apache/geode/cache/configuration/JndiBindingsType.html
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
index bef7d90..de3a82f 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/LocatorClusterManagementService.java
@@ -35,6 +35,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.cache.configuration.CacheConfig;
 import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.cache.configuration.PdxType;
 import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.cache.execute.Function;
@@ -52,6 +53,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.functions.UpdateCacheFunction;
 import org.apache.geode.management.internal.configuration.mutators.ConfigurationManager;
+import org.apache.geode.management.internal.configuration.mutators.GatewayReceiverConfigManager;
 import org.apache.geode.management.internal.configuration.mutators.MemberConfigManager;
 import org.apache.geode.management.internal.configuration.mutators.PdxManager;
 import org.apache.geode.management.internal.configuration.mutators.RegionConfigManager;
@@ -75,6 +77,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
     managers.put(RegionConfig.class, new RegionConfigManager(cache));
     managers.put(MemberConfig.class, new MemberConfigManager(cache));
     managers.put(PdxType.class, new PdxManager());
+    managers.put(GatewayReceiverConfig.class, new GatewayReceiverConfigManager(cache));
 
     // initialize the list of validators
     validators.put(CacheElement.class, new CacheElementValidator());
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateGatewayReceiverCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateGatewayReceiverCommand.java
index cedb65e..774f35c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateGatewayReceiverCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateGatewayReceiverCommand.java
@@ -25,6 +25,7 @@ import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.cache.configuration.CacheConfig;
 import org.apache.geode.cache.configuration.DeclarableType;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.cache.wan.GatewayReceiver;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.management.cli.CliMetaData;
@@ -84,7 +85,7 @@ public class CreateGatewayReceiverCommand extends SingleGfshCommand {
       @CliOption(key = CliStrings.IFNOTEXISTS, help = CliStrings.IFNOTEXISTS_HELP,
           specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") Boolean ifNotExists) {
 
-    CacheConfig.GatewayReceiver configuration =
+    GatewayReceiverConfig configuration =
         buildConfiguration(manualStart, startPort, endPort, bindAddress, maximumTimeBetweenPings,
             socketBufferSize, gatewayTransportFilters, hostnameForSenders);
 
@@ -104,14 +105,14 @@ public class CreateGatewayReceiverCommand extends SingleGfshCommand {
 
   @Override
   public boolean updateConfigForGroup(String group, CacheConfig config, Object configObject) {
-    config.setGatewayReceiver((CacheConfig.GatewayReceiver) configObject);
+    config.setGatewayReceiver((GatewayReceiverConfig) configObject);
     return true;
   }
 
-  private CacheConfig.GatewayReceiver buildConfiguration(Boolean manualStart, Integer startPort,
+  private GatewayReceiverConfig buildConfiguration(Boolean manualStart, Integer startPort,
       Integer endPort, String bindAddress, Integer maximumTimeBetweenPings,
       Integer socketBufferSize, String[] gatewayTransportFilters, String hostnameForSenders) {
-    CacheConfig.GatewayReceiver configuration = new CacheConfig.GatewayReceiver();
+    GatewayReceiverConfig configuration = new GatewayReceiverConfig();
 
     if (gatewayTransportFilters != null) {
       List<DeclarableType> filters =
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyGatewayReceiverCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyGatewayReceiverCommand.java
index 85a65fa..6b89fe9 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyGatewayReceiverCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyGatewayReceiverCommand.java
@@ -21,6 +21,7 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
@@ -62,7 +63,7 @@ public class DestroyGatewayReceiverCommand extends SingleGfshCommand {
         executeAndGetFunctionResult(DestroyGatewayReceiverFunction.INSTANCE, null, members);
 
     ResultModel result = ResultModel.createMemberStatusResult(functionResults, ifExists);
-    result.setConfigObject(new CacheConfig.GatewayReceiver());
+    result.setConfigObject(new GatewayReceiverConfig());
 
 
     return result;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GatewayReceiverFunctionArgs.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GatewayReceiverFunctionArgs.java
index 07d7083..6c4bfe0 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GatewayReceiverFunctionArgs.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GatewayReceiverFunctionArgs.java
@@ -16,8 +16,8 @@ package org.apache.geode.management.internal.cli.functions;
 
 import java.io.Serializable;
 
-import org.apache.geode.cache.configuration.CacheConfig.GatewayReceiver;
 import org.apache.geode.cache.configuration.DeclarableType;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 
 /**
  * This class stores the arguments provided in the create gateway-receiver command.
@@ -43,7 +43,7 @@ public class GatewayReceiverFunctionArgs implements Serializable {
 
   private final Boolean ifNotExists;
 
-  public GatewayReceiverFunctionArgs(GatewayReceiver configuration, Boolean ifNotExists) {
+  public GatewayReceiverFunctionArgs(GatewayReceiverConfig configuration, Boolean ifNotExists) {
     this.manualStart = configuration.isManualStart();
     this.startPort =
         configuration.getStartPort() != null ? Integer.valueOf(configuration.getStartPort()) : null;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/GatewayReceiverConfigManager.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/GatewayReceiverConfigManager.java
new file mode 100644
index 0000000..66515a2
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/mutators/GatewayReceiverConfigManager.java
@@ -0,0 +1,57 @@
+/*
+ * 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.configuration.mutators;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
+import org.apache.geode.internal.cache.InternalCache;
+
+public class GatewayReceiverConfigManager implements ConfigurationManager<GatewayReceiverConfig> {
+  private final InternalCache cache;
+
+  public GatewayReceiverConfigManager(InternalCache cache) {
+    this.cache = cache;
+  }
+
+
+  @Override
+  public void add(GatewayReceiverConfig config, CacheConfig existing) {
+
+  }
+
+  @Override
+  public void update(GatewayReceiverConfig config, CacheConfig existing) {
+
+  }
+
+  @Override
+  public void delete(GatewayReceiverConfig config, CacheConfig existing) {
+
+  }
+
+  @Override
+  public List<? extends GatewayReceiverConfig> list(GatewayReceiverConfig filterConfig,
+      CacheConfig existing) {
+    GatewayReceiverConfig gatewayReceiver = existing.getGatewayReceiver();
+    if (gatewayReceiver == null) {
+      return Collections.emptyList();
+    }
+    return Collections.singletonList(gatewayReceiver);
+  }
+}
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
index 3cb35c7..8135f2d 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-management-serializables.txt
@@ -6,6 +6,7 @@ org/apache/geode/cache/configuration/DiskDirsType,false,diskDirs:java/util/List
 org/apache/geode/cache/configuration/DiskStoreType,false,allowForceCompaction:java/lang/Boolean,autoCompact:java/lang/Boolean,compactionThreshold:java/lang/String,diskDirs:org/apache/geode/cache/configuration/DiskDirsType,diskUsageCriticalPercentage:java/lang/String,diskUsageWarningPercentage:java/lang/String,maxOplogSize:java/lang/String,name:java/lang/String,queueSize:java/lang/String,timeInterval:java/lang/String,writeBufferSize:java/lang/String
 org/apache/geode/cache/configuration/EnumActionDestroyOverflow,false,value:java/lang/String
 org/apache/geode/cache/configuration/EnumReadableWritable,false,value:java/lang/String
+org/apache/geode/cache/configuration/GatewayReceiverConfig,false,bindAddress:java/lang/String,endPort:java/lang/String,gatewayTransportFilters:java/util/List,hostnameForSenders:java/lang/String,manualStart:java/lang/Boolean,maximumTimeBetweenPings:java/lang/String,socketBufferSize:java/lang/String,startPort:java/lang/String
 org/apache/geode/cache/configuration/JndiBindingsType$JndiBinding,false,blockingTimeoutSeconds:java/lang/String,configProperties:java/util/List,connPooledDatasourceClass:java/lang/String,connectionUrl:java/lang/String,idleTimeoutSeconds:java/lang/String,initPoolSize:java/lang/String,jdbcDriverClass:java/lang/String,jndiName:java/lang/String,loginTimeoutSeconds:java/lang/String,managedConnFactoryClass:java/lang/String,maxPoolSize:java/lang/String,password:java/lang/String,transactionType: [...]
 org/apache/geode/cache/configuration/JndiBindingsType$JndiBinding$ConfigProperty,false,configPropertyName:java/lang/String,configPropertyType:java/lang/String,configPropertyValue:java/lang/String
 org/apache/geode/cache/configuration/ObjectType,false,declarable:org/apache/geode/cache/configuration/DeclarableType,string:java/lang/String
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceServiceTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceServiceTest.java
index 5e6d611..47bdf16 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceServiceTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceServiceTest.java
@@ -44,6 +44,7 @@ import org.w3c.dom.Document;
 
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.configuration.CacheConfig;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.cache.configuration.JndiBindingsType;
 import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.cache.configuration.RegionType;
@@ -207,7 +208,7 @@ public class InternalConfigurationPersistenceServiceTest {
   @Test
   public void updateGatewayReceiverConfig() {
     service.updateCacheConfig("cluster", cacheConfig -> {
-      CacheConfig.GatewayReceiver receiver = new CacheConfig.GatewayReceiver();
+      GatewayReceiverConfig receiver = new GatewayReceiverConfig();
       cacheConfig.setGatewayReceiver(receiver);
       return cacheConfig;
     });
diff --git a/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java b/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java
index 99dc8e8..8be1774 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java
@@ -33,6 +33,7 @@ import org.junit.Test;
 
 import org.apache.geode.cache.configuration.CacheConfig;
 import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.cache.configuration.RegionType;
 
@@ -209,7 +210,7 @@ public class JAXBServiceTest {
 
   public static void setBasicValues(CacheConfig cache) {
     cache.setCopyOnRead(true);
-    CacheConfig.GatewayReceiver receiver = new CacheConfig.GatewayReceiver();
+    GatewayReceiverConfig receiver = new GatewayReceiverConfig();
     receiver.setBindAddress("localhost");
     receiver.setEndPort("8080");
     receiver.setManualStart(false);
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheConfig.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheConfig.java
index dcacf5f..337b80b 100644
--- a/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheConfig.java
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/CacheConfig.java
@@ -280,7 +280,7 @@ public class CacheConfig {
   @XmlElement(name = "gateway-sender", namespace = "http://geode.apache.org/schema/cache")
   protected List<GatewaySender> gatewaySenders;
   @XmlElement(name = "gateway-receiver", namespace = "http://geode.apache.org/schema/cache")
-  protected CacheConfig.GatewayReceiver gatewayReceiver;
+  protected GatewayReceiverConfig gatewayReceiver;
   @XmlElement(name = "gateway-conflict-resolver",
       namespace = "http://geode.apache.org/schema/cache")
   protected DeclarableType gatewayConflictResolver;
@@ -446,10 +446,10 @@ public class CacheConfig {
    * Gets the value of the gatewayReceiver property.
    *
    * possible object is
-   * {@link CacheConfig.GatewayReceiver }
+   * {@link GatewayReceiverConfig }
    *
    */
-  public CacheConfig.GatewayReceiver getGatewayReceiver() {
+  public GatewayReceiverConfig getGatewayReceiver() {
     return gatewayReceiver;
   }
 
@@ -457,10 +457,10 @@ public class CacheConfig {
    * Sets the value of the gatewayReceiver property.
    *
    * allowed object is
-   * {@link CacheConfig.GatewayReceiver }
+   * {@link GatewayReceiverConfig }
    *
    */
-  public void setGatewayReceiver(CacheConfig.GatewayReceiver value) {
+  public void setGatewayReceiver(GatewayReceiverConfig value) {
     this.gatewayReceiver = value;
   }
 
@@ -2536,243 +2536,6 @@ public class CacheConfig {
    *   &lt;complexContent>
    *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    *       &lt;sequence>
-   *         &lt;element name="gateway-transport-filter" type="{http://geode.apache.org/schema/cache}class-with-parameters-type" maxOccurs="unbounded" minOccurs="0"/>
-   *       &lt;/sequence>
-   *       &lt;attribute name="start-port" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="end-port" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="bind-address" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="maximum-time-between-pings" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="socket-buffer-size" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="hostname-for-senders" type="{http://www.w3.org/2001/XMLSchema}string" />
-   *       &lt;attribute name="manual-start" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-   *     &lt;/restriction>
-   *   &lt;/complexContent>
-   * &lt;/complexType>
-   * </pre>
-   *
-   *
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  @XmlType(name = "", propOrder = {"gatewayTransportFilters"})
-  public static class GatewayReceiver {
-
-    @XmlElement(name = "gateway-transport-filter",
-        namespace = "http://geode.apache.org/schema/cache")
-    protected List<DeclarableType> gatewayTransportFilters;
-    @XmlAttribute(name = "start-port")
-    protected String startPort;
-    @XmlAttribute(name = "end-port")
-    protected String endPort;
-    @XmlAttribute(name = "bind-address")
-    protected String bindAddress;
-    @XmlAttribute(name = "maximum-time-between-pings")
-    protected String maximumTimeBetweenPings;
-    @XmlAttribute(name = "socket-buffer-size")
-    protected String socketBufferSize;
-    @XmlAttribute(name = "hostname-for-senders")
-    protected String hostnameForSenders;
-    @XmlAttribute(name = "manual-start")
-    protected Boolean manualStart;
-
-    /**
-     * Gets the value of the gatewayTransportFilters property.
-     *
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the gatewayTransportFilters property.
-     *
-     * <p>
-     * For example, to add a new item, do as follows:
-     *
-     * <pre>
-     * getGatewayTransportFilters().add(newItem);
-     * </pre>
-     *
-     *
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DeclarableType }
-     *
-     *
-     */
-    public List<DeclarableType> getGatewayTransportFilters() {
-      if (gatewayTransportFilters == null) {
-        gatewayTransportFilters = new ArrayList<DeclarableType>();
-      }
-      return this.gatewayTransportFilters;
-    }
-
-    /**
-     * Gets the value of the startPort property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getStartPort() {
-      return startPort;
-    }
-
-    /**
-     * Sets the value of the startPort property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setStartPort(String value) {
-      this.startPort = value;
-    }
-
-    /**
-     * Gets the value of the endPort property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getEndPort() {
-      return endPort;
-    }
-
-    /**
-     * Sets the value of the endPort property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setEndPort(String value) {
-      this.endPort = value;
-    }
-
-    /**
-     * Gets the value of the bindAddress property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getBindAddress() {
-      return bindAddress;
-    }
-
-    /**
-     * Sets the value of the bindAddress property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setBindAddress(String value) {
-      this.bindAddress = value;
-    }
-
-    /**
-     * Gets the value of the maximumTimeBetweenPings property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getMaximumTimeBetweenPings() {
-      return maximumTimeBetweenPings;
-    }
-
-    /**
-     * Sets the value of the maximumTimeBetweenPings property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setMaximumTimeBetweenPings(String value) {
-      this.maximumTimeBetweenPings = value;
-    }
-
-    /**
-     * Gets the value of the socketBufferSize property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getSocketBufferSize() {
-      return socketBufferSize;
-    }
-
-    /**
-     * Sets the value of the socketBufferSize property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setSocketBufferSize(String value) {
-      this.socketBufferSize = value;
-    }
-
-    /**
-     * Gets the value of the hostnameForSenders property.
-     *
-     * possible object is
-     * {@link String }
-     *
-     */
-    public String getHostnameForSenders() {
-      return hostnameForSenders;
-    }
-
-    /**
-     * Sets the value of the hostnameForSenders property.
-     *
-     * allowed object is
-     * {@link String }
-     *
-     */
-    public void setHostnameForSenders(String value) {
-      this.hostnameForSenders = value;
-    }
-
-    /**
-     * Gets the value of the manualStart property.
-     *
-     * possible object is
-     * {@link Boolean }
-     *
-     */
-    public Boolean isManualStart() {
-      return manualStart;
-    }
-
-    /**
-     * Sets the value of the manualStart property.
-     *
-     * allowed object is
-     * {@link Boolean }
-     *
-     */
-    public void setManualStart(Boolean value) {
-      this.manualStart = value;
-    }
-
-  }
-
-
-  /**
-   * <p>
-   * Java class for anonymous complex type.
-   *
-   * <p>
-   * The following schema fragment specifies the expected content contained within this class.
-   *
-   * <pre>
-   * &lt;complexType>
-   *   &lt;complexContent>
-   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-   *       &lt;sequence>
    *         &lt;element name="gateway-event-filter" type="{http://geode.apache.org/schema/cache}class-with-parameters-type" maxOccurs="unbounded" minOccurs="0"/>
    *         &lt;element name="gateway-event-substitution-filter" type="{http://geode.apache.org/schema/cache}class-with-parameters-type" minOccurs="0"/>
    *         &lt;element name="gateway-transport-filter" type="{http://geode.apache.org/schema/cache}class-with-parameters-type" maxOccurs="unbounded" minOccurs="0"/>
diff --git a/geode-management/src/main/java/org/apache/geode/cache/configuration/GatewayReceiverConfig.java b/geode-management/src/main/java/org/apache/geode/cache/configuration/GatewayReceiverConfig.java
new file mode 100644
index 0000000..3a407d7
--- /dev/null
+++ b/geode-management/src/main/java/org/apache/geode/cache/configuration/GatewayReceiverConfig.java
@@ -0,0 +1,291 @@
+/*
+ * 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.cache.configuration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.geode.management.api.RestfulEndpoint;
+
+/**
+ * <p>
+ * Java class for anonymous complex type.
+ *
+ * <p>
+ * The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="gateway-transport-filter" type="{http://geode.apache.org/schema/cache}class-with-parameters-type" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attribute name="start-port" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="end-port" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="bind-address" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="maximum-time-between-pings" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="socket-buffer-size" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="hostname-for-senders" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       &lt;attribute name="manual-start" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {"gatewayTransportFilters"})
+public class GatewayReceiverConfig extends CacheElement implements RestfulEndpoint {
+
+  @XmlElement(name = "gateway-transport-filter",
+      namespace = "http://geode.apache.org/schema/cache")
+  protected List<DeclarableType> gatewayTransportFilters;
+  @XmlAttribute(name = "start-port")
+  protected String startPort;
+  @XmlAttribute(name = "end-port")
+  protected String endPort;
+  @XmlAttribute(name = "bind-address")
+  protected String bindAddress;
+  @XmlAttribute(name = "maximum-time-between-pings")
+  protected String maximumTimeBetweenPings;
+  @XmlAttribute(name = "socket-buffer-size")
+  protected String socketBufferSize;
+  @XmlAttribute(name = "hostname-for-senders")
+  protected String hostnameForSenders;
+  @XmlAttribute(name = "manual-start")
+  protected Boolean manualStart;
+
+  /**
+   * Gets the value of the gatewayTransportFilters property.
+   *
+   * <p>
+   * This accessor method returns a reference to the live list,
+   * not a snapshot. Therefore any modification you make to the
+   * returned list will be present inside the JAXB object.
+   * This is why there is not a <CODE>set</CODE> method for the gatewayTransportFilters property.
+   *
+   * <p>
+   * For example, to add a new item, do as follows:
+   *
+   * <pre>
+   * getGatewayTransportFilters().add(newItem);
+   * </pre>
+   *
+   *
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DeclarableType }
+   *
+   *
+   */
+  public List<DeclarableType> getGatewayTransportFilters() {
+    if (gatewayTransportFilters == null) {
+      gatewayTransportFilters = new ArrayList<DeclarableType>();
+    }
+    return this.gatewayTransportFilters;
+  }
+
+  /**
+   * Gets the value of the startPort property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getStartPort() {
+    return startPort;
+  }
+
+  /**
+   * Sets the value of the startPort property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setStartPort(String value) {
+    this.startPort = value;
+  }
+
+  /**
+   * Gets the value of the endPort property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getEndPort() {
+    return endPort;
+  }
+
+  /**
+   * Sets the value of the endPort property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setEndPort(String value) {
+    this.endPort = value;
+  }
+
+  /**
+   * Gets the value of the bindAddress property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getBindAddress() {
+    return bindAddress;
+  }
+
+  /**
+   * Sets the value of the bindAddress property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setBindAddress(String value) {
+    this.bindAddress = value;
+  }
+
+  /**
+   * Gets the value of the maximumTimeBetweenPings property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getMaximumTimeBetweenPings() {
+    return maximumTimeBetweenPings;
+  }
+
+  /**
+   * Sets the value of the maximumTimeBetweenPings property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setMaximumTimeBetweenPings(String value) {
+    this.maximumTimeBetweenPings = value;
+  }
+
+  /**
+   * Gets the value of the socketBufferSize property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getSocketBufferSize() {
+    return socketBufferSize;
+  }
+
+  /**
+   * Sets the value of the socketBufferSize property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setSocketBufferSize(String value) {
+    this.socketBufferSize = value;
+  }
+
+  /**
+   * Gets the value of the hostnameForSenders property.
+   *
+   * possible object is
+   * {@link String }
+   *
+   */
+  public String getHostnameForSenders() {
+    return hostnameForSenders;
+  }
+
+  /**
+   * Sets the value of the hostnameForSenders property.
+   *
+   * allowed object is
+   * {@link String }
+   *
+   */
+  public void setHostnameForSenders(String value) {
+    this.hostnameForSenders = value;
+  }
+
+  /**
+   * Gets the value of the manualStart property.
+   *
+   * possible object is
+   * {@link Boolean }
+   *
+   */
+  public Boolean isManualStart() {
+    return manualStart;
+  }
+
+  /**
+   * Sets the value of the manualStart property.
+   *
+   * allowed object is
+   * {@link Boolean }
+   *
+   */
+  public void setManualStart(Boolean value) {
+    this.manualStart = value;
+  }
+
+
+  @Override
+  @XmlTransient
+  @JsonIgnore
+  public String getId() {
+    return getGroup();
+  }
+
+  public static final String GATEWAY_RECEIVERS_ENDPOINTS = "/gateways/receivers";
+
+  @Override
+  @XmlTransient
+  @JsonIgnore
+  public String getEndpoint() {
+    return GATEWAY_RECEIVERS_ENDPOINTS;
+  }
+
+  @Override
+  @XmlTransient
+  public String getUri() {
+    if (StringUtils.isBlank(getGroup())) {
+      return getEndpoint() + "/cluster";
+    }
+    return getEndpoint() + "/" + getGroup();
+  }
+}
diff --git a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java
index 47d9741..ea90c4f 100644
--- a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java
+++ b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java
@@ -47,4 +47,8 @@ public class PlainLocatorContextLoader extends BaseLocatorContextLoader {
   public ClusterManagementService getClusterManagementService() {
     return locator.getLocator().getClusterManagementService();
   }
+
+  public LocatorStarterRule getLocatorStartupRule() {
+    return locator;
+  }
 }
diff --git a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/GatewayManagementIntegrationTest.java b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/GatewayManagementIntegrationTest.java
new file mode 100644
index 0000000..075c721
--- /dev/null
+++ b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/GatewayManagementIntegrationTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.management.internal.rest;
+
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.context.WebApplicationContext;
+
+import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
+import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
+import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.api.ClusterManagementService;
+import org.apache.geode.management.client.ClusterManagementServiceBuilder;
+import org.apache.geode.test.junit.rules.LocatorStarterRule;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-management-servlet.xml"},
+    loader = PlainLocatorContextLoader.class)
+@WebAppConfiguration
+public class GatewayManagementIntegrationTest {
+
+  @Autowired
+  private WebApplicationContext webApplicationContext;
+
+  // needs to be used together with any BaseLocatorContextLoader
+  private LocatorWebContext context;
+
+  private ClusterManagementService client;
+
+  private GatewayReceiverConfig filter;
+
+  @Before
+  public void before() {
+    context = new LocatorWebContext(webApplicationContext);
+    client = ClusterManagementServiceBuilder.buildWithRequestFactory()
+        .setRequestFactory(context.getRequestFactory()).build();
+    filter = new GatewayReceiverConfig();
+  }
+
+  @Test
+  public void listEmptyGatewayReceivers() {
+    ClusterManagementResult result = client.list(filter);
+    assertThat(result.isSuccessful()).isTrue();
+    assertThat(result.getResult(CacheElement.class).size()).isEqualTo(0);
+  }
+
+  @Test
+  public void listExisting() {
+    LocatorStarterRule locator =
+        ((PlainLocatorContextLoader) context.getLocator()).getLocatorStartupRule();
+    InternalConfigurationPersistenceService cps =
+        locator.getLocator().getConfigurationPersistenceService();
+
+    // manually create a gateway receiver in cluster group
+    cps.updateCacheConfig("cluster", cacheConfig -> {
+      GatewayReceiverConfig receiver = new GatewayReceiverConfig();
+      receiver.setBindAddress("localhost");
+      receiver.setManualStart(false);
+      receiver.setStartPort("5000");
+      cacheConfig.setGatewayReceiver(receiver);
+      return cacheConfig;
+    });
+
+    ClusterManagementResult result = client.list(filter);
+    assertThat(result.isSuccessful()).isTrue();
+    List<GatewayReceiverConfig> receivers =
+        result.getResult(GatewayReceiverConfig.class);
+    assertThat(receivers.size()).isEqualTo(1);
+    GatewayReceiverConfig receiver = receivers.get(0);
+    assertThat(receiver.getBindAddress()).isEqualTo("localhost");
+    assertThat(receiver.isManualStart()).isFalse();
+    assertThat(receiver.getStartPort()).isEqualTo("5000");
+
+    // manually removing the GWR so that it won't pollute other tests
+    cps.updateCacheConfig("cluster", cacheConfig -> {
+      cacheConfig.setGatewayReceiver(null);
+      return cacheConfig;
+    });
+  }
+}
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java
new file mode 100644
index 0000000..7ba9f45
--- /dev/null
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/GatewayManagementController.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.management.internal.rest.controllers;
+
+import static org.apache.geode.cache.configuration.GatewayReceiverConfig.GATEWAY_RECEIVERS_ENDPOINTS;
+import static org.apache.geode.management.internal.rest.controllers.AbstractManagementController.MANAGEMENT_API_VERSION;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import org.apache.geode.cache.configuration.GatewayReceiverConfig;
+import org.apache.geode.management.api.ClusterManagementResult;
+
+@Controller("gatewayManagement")
+@RequestMapping(MANAGEMENT_API_VERSION)
+public class GatewayManagementController extends AbstractManagementController {
+
+  @PreAuthorize("@securityService.authorize('CLUSTER', 'READ')")
+  @RequestMapping(method = RequestMethod.GET, value = GATEWAY_RECEIVERS_ENDPOINTS)
+  @ResponseBody
+  public ClusterManagementResult listGatewayReceivers(
+      @RequestParam(required = false) String group) {
+    GatewayReceiverConfig filter = new GatewayReceiverConfig();
+    if (StringUtils.isNotBlank(group)) {
+      filter.setGroup(group);
+    }
+    return clusterManagementService.list(filter);
+  }
+}