geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From onich...@apache.org
Subject [geode] branch develop updated: GEODE-7024: raise a Java exception on non-success response from REST API (#3861)
Date Thu, 01 Aug 2019 04:10:33 GMT
This is an automated email from the ASF dual-hosted git repository.

onichols 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 e2855b4  GEODE-7024: raise a Java exception on non-success response from REST API (#3861)
e2855b4 is described below

commit e2855b4d2359c8a7f402f8dbd011292645b94b5a
Author: Owen Nichols <34043438+onichols-pivotal@users.noreply.github.com>
AuthorDate: Wed Jul 31 21:10:06 2019 -0700

    GEODE-7024: raise a Java exception on non-success response from REST API (#3861)
    
    * GEODE-7024: raise a Java exception on non-success response from REST call
---
 ...ateRegionWithDiskstoreAndSecurityDUnitTest.java |  13 +--
 .../rest/ClientClusterManagementSSLTest.java       |  33 ++----
 .../ClientClusterManagementServiceDunitTest.java   |  11 +-
 .../rest/GatewayReceiverManagementDUnitTest.java   |  12 +--
 .../rest/ListIndexManagementDUnitTest.java         |   8 +-
 .../internal/rest/RegionManagementDunitTest.java   |  17 ++--
 .../integrationTest/resources/assembly_content.txt |   2 +
 .../apache/geode/codeAnalysis/excludedClasses.txt  |   2 +
 .../api/LocatorClusterManagementService.java       | 112 ++++++++++++++-------
 .../api/LocatorClusterManagementServiceTest.java   |  50 +++++----
 .../management/api/ClusterManagementException.java |  60 +++++++++++
 .../api/ClusterManagementRealizationException.java |  43 ++++++++
 .../management/api/ClusterManagementResult.java    |  14 +++
 .../management/api/ClusterManagementService.java   |  11 +-
 .../internal/ClientClusterManagementService.java   |  42 +++++---
 .../ClientClusterManagementServiceDUnitTest.java   |  18 ++--
 .../rest/GatewayManagementIntegrationTest.java     |  11 +-
 .../rest/RegionManagementIntegrationTest.java      |  20 ++--
 .../controllers/ManagementControllerAdvice.java    |  54 ++++++----
 .../controllers/MemberManagementController.java    |   8 +-
 .../controllers/RegionManagementController.java    |   9 +-
 21 files changed, 348 insertions(+), 202 deletions(-)

diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/client/CreateRegionWithDiskstoreAndSecurityDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/client/CreateRegionWithDiskstoreAndSecurityDUnitTest.java
index 3d07970..6ca28bb 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/client/CreateRegionWithDiskstoreAndSecurityDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/client/CreateRegionWithDiskstoreAndSecurityDUnitTest.java
@@ -16,6 +16,7 @@
 package org.apache.geode.management.client;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.io.File;
 
@@ -84,10 +85,8 @@ public class CreateRegionWithDiskstoreAndSecurityDUnitTest {
         ClusterManagementServiceBuilder.buildWithHostAddress()
             .setHostAddress("localhost", locator.getHttpPort())
             .setCredentials("user", "user").build();
-    ClusterManagementResult result = client.create(regionConfig);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.UNAUTHORIZED);
-    assertThat(result.getStatusMessage()).isEqualTo("user not authorized for DATA:MANAGE");
+    assertThatThrownBy(() -> client.create(regionConfig))
+        .hasMessageContaining("UNAUTHORIZED: user not authorized for DATA:MANAGE");
   }
 
   @Test
@@ -109,10 +108,8 @@ public class CreateRegionWithDiskstoreAndSecurityDUnitTest {
         ClusterManagementServiceBuilder.buildWithHostAddress()
             .setHostAddress("localhost", locator.getHttpPort())
             .setCredentials("data", "data").build();
-    ClusterManagementResult result = client.create(regionConfig);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.UNAUTHORIZED);
-    assertThat(result.getStatusMessage()).isEqualTo("data not authorized for CLUSTER:WRITE:DISK");
+    assertThatThrownBy(() -> client.create(regionConfig))
+        .hasMessageContaining("UNAUTHORIZED: data not authorized for CLUSTER:WRITE:DISK");
   }
 
   @Test
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
index 7a95283..758f1c9 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementSSLTest.java
@@ -91,7 +91,7 @@ public class ClientClusterManagementSSLTest {
   }
 
   @Test
-  public void createRegion_Successful() throws Exception {
+  public void createRegion_Successful() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -115,7 +115,7 @@ public class ClientClusterManagementSSLTest {
   }
 
   @Test
-  public void createRegion_NoSsl() throws Exception {
+  public void createRegion_NoSsl() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -132,7 +132,7 @@ public class ClientClusterManagementSSLTest {
   }
 
   @Test
-  public void createRegion_WrongPassword() throws Exception {
+  public void createRegion_WrongPassword() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -147,15 +147,12 @@ public class ClientClusterManagementSSLTest {
           .setHostnameVerifier(hostnameVerifier)
           .setCredentials("dataManage", "wrongPassword").build();
 
-      ClusterManagementResult result = cmsClient.create(region);
-      assertThat(result.isSuccessful()).isFalse();
-      assertThat(result.getStatusCode())
-          .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+      assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("UNAUTHENTICATED");
     });
   }
 
   @Test
-  public void createRegion_NoUser() throws Exception {
+  public void createRegion_NoUser() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -171,15 +168,12 @@ public class ClientClusterManagementSSLTest {
           .setHostnameVerifier(hostnameVerifier)
           .build();
 
-      ClusterManagementResult result = cmsClient.create(region);
-      assertThat(result.isSuccessful()).isFalse();
-      assertThat(result.getStatusCode())
-          .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+      assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("UNAUTHENTICATED");
     });
   }
 
   @Test
-  public void createRegion_NoPassword() throws Exception {
+  public void createRegion_NoPassword() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -194,15 +188,12 @@ public class ClientClusterManagementSSLTest {
           .setHostnameVerifier(hostnameVerifier)
           .setCredentials("dataManage", null).build();
 
-      ClusterManagementResult result = cmsClient.create(region);
-      assertThat(result.isSuccessful()).isFalse();
-      assertThat(result.getStatusCode())
-          .isEqualTo(ClusterManagementResult.StatusCode.UNAUTHENTICATED);
+      assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("UNAUTHENTICATED");
     });
   }
 
   @Test
-  public void createRegion_NoPrivilege() throws Exception {
+  public void createRegion_NoPrivilege() {
     RegionConfig region = new RegionConfig();
     region.setName("customer");
     region.setType(RegionType.PARTITION);
@@ -217,14 +208,12 @@ public class ClientClusterManagementSSLTest {
           .setHostnameVerifier(hostnameVerifier)
           .setCredentials("dataRead", "dataRead").build();
 
-      ClusterManagementResult result = cmsClient.create(region);
-      assertThat(result.isSuccessful()).isFalse();
-      assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.UNAUTHORIZED);
+      assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("UNAUTHORIZED");
     });
   }
 
   @Test
-  public void invokeFromServer() throws Exception {
+  public void invokeFromServer() {
     server.invoke(() -> {
       // when getting the service from the server, we don't need to provide the host information
       ClusterManagementService cmsClient = buildWithCache()
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
index 051b542..5f1abaf 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ClientClusterManagementServiceDunitTest.java
@@ -69,9 +69,7 @@ public class ClientClusterManagementServiceDunitTest {
     assertThat(result.getMemberStatuses()).extracting(RealizationResult::getMemberName)
         .containsExactlyInAnyOrder("server-1", "server-2");
 
-    result = cmsClient.create(region);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusCode()).isEqualTo(ClusterManagementResult.StatusCode.ENTITY_EXISTS);
+    assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("ENTITY_EXISTS");
   }
 
   @Test
@@ -90,14 +88,11 @@ public class ClientClusterManagementServiceDunitTest {
 
 
   @Test
-  public void createRegionWithInvalidName() throws Exception {
+  public void createRegionWithInvalidName() {
     RegionConfig region = new RegionConfig();
     region.setName("__test");
 
-    ClusterManagementResult result = cmsClient.create(region);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusCode())
-        .isEqualTo(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT);
+    assertThatThrownBy(() -> cmsClient.create(region)).hasMessageContaining("ILLEGAL_ARGUMENT");
   }
 
   @Test
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/GatewayReceiverManagementDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/GatewayReceiverManagementDUnitTest.java
index a1a8e59..908f1e7 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/GatewayReceiverManagementDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/GatewayReceiverManagementDUnitTest.java
@@ -18,6 +18,7 @@ package org.apache.geode.management.internal.rest;
 import static org.apache.geode.test.junit.assertions.ClusterManagementListResultAssert.assertManagementListResult;
 import static org.apache.geode.test.junit.assertions.ClusterManagementRealizationResultAssert.assertManagementResult;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.List;
 
@@ -27,7 +28,6 @@ import org.junit.ClassRule;
 import org.junit.Test;
 
 import org.apache.geode.cache.configuration.GatewayReceiverConfig;
-import org.apache.geode.management.api.ClusterManagementResult;
 import org.apache.geode.management.api.ClusterManagementService;
 import org.apache.geode.management.api.ConfigurationResult;
 import org.apache.geode.management.api.RealizationResult;
@@ -77,9 +77,8 @@ public class GatewayReceiverManagementDUnitTest {
     // try create another GWR on the same group
     receiver.setStartPort("5001");
     receiver.setGroup("group1");
-    assertManagementResult(cms.create(receiver)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ENTITY_EXISTS)
-        .containsStatusMessage("Member(s) server-1 already has this element created");
+    assertThatThrownBy(() -> cms.create(receiver))
+        .hasMessageContaining("ENTITY_EXISTS: Member(s) server-1 already has this element created");
 
     // try create another GWR on another group but has no server
     receiver.setStartPort("5002");
@@ -91,9 +90,8 @@ public class GatewayReceiverManagementDUnitTest {
     // try create another GWR on another group but has a common member in another group
     receiver.setStartPort("5003");
     receiver.setGroup(null);
-    assertManagementResult(cms.create(receiver)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ENTITY_EXISTS)
-        .containsStatusMessage("Member(s) server-1 already has this element created");
+    assertThatThrownBy(() -> cms.create(receiver))
+        .hasMessageContaining("ENTITY_EXISTS: Member(s) server-1 already has this element created");
 
     ClusterManagementListResultAssert<GatewayReceiverConfig, GatewayReceiverInfo> listAssert =
         assertManagementListResult(cms.list(new GatewayReceiverConfig())).isSuccessful();
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListIndexManagementDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListIndexManagementDUnitTest.java
index 9300ec6..0a1708a 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListIndexManagementDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/ListIndexManagementDUnitTest.java
@@ -15,7 +15,6 @@
 
 package org.apache.geode.management.internal.rest;
 
-import static org.apache.geode.test.junit.assertions.ClusterManagementListResultAssert.assertManagementListResult;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -29,7 +28,6 @@ import org.junit.Test;
 import org.apache.geode.cache.configuration.RegionConfig;
 import org.apache.geode.cache.configuration.RegionType;
 import org.apache.geode.management.api.ClusterManagementListResult;
-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.management.runtime.RuntimeInfo;
@@ -99,8 +97,7 @@ public class ListIndexManagementDUnitTest {
   @Test
   public void getNonExistRegion() {
     regionConfig.setName("notExist");
-    assertManagementListResult(cms.get(regionConfig)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ENTITY_NOT_FOUND);
+    assertThatThrownBy(() -> cms.get(regionConfig)).hasMessageContaining("ENTITY_NOT_FOUND");
   }
 
   @Test
@@ -163,8 +160,7 @@ public class ListIndexManagementDUnitTest {
     RegionConfig.Index index = new RegionConfig.Index();
     index.setRegionName("region1");
     index.setName("index333");
-    assertManagementListResult(cms.get(index)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ENTITY_NOT_FOUND);
+    assertThatThrownBy(() -> cms.get(index)).hasMessageContaining("ENTITY_NOT_FOUND");
   }
 
   @Test
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java
index b05161f..08b1517 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/rest/RegionManagementDunitTest.java
@@ -194,16 +194,14 @@ public class RegionManagementDunitTest {
     regionConfig.setType(RegionType.REPLICATE);
     assertManagementResult(cms.create(regionConfig)).isSuccessful();
 
-    assertManagementResult(cms.create(regionConfig)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ENTITY_EXISTS)
-        .containsStatusMessage("server-2")
-        .containsStatusMessage("server-3")
-        .containsStatusMessage("already has this element created");
+    assertThatThrownBy(() -> cms.create(regionConfig)).hasMessageContaining("ENTITY_EXISTS")
+        .hasMessageContaining("server-2")
+        .hasMessageContaining("server-3")
+        .hasMessageContaining("already has this element created");
 
     regionConfig.setGroup("group3");
-    assertManagementResult(cms.create(regionConfig)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ENTITY_EXISTS)
-        .containsStatusMessage("Member(s) server-3 already has this element created");
+    assertThatThrownBy(() -> cms.create(regionConfig)).hasMessageContaining("ENTITY_EXISTS")
+        .hasMessageContaining("Member(s) server-3 already has this element created");
   }
 
   @Test
@@ -217,8 +215,7 @@ public class RegionManagementDunitTest {
     regionConfig.setName("incompatible");
     regionConfig.setGroup("group5");
     regionConfig.setType(RegionType.PARTITION);
-    assertManagementResult(cms.create(regionConfig)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT);
+    assertThatThrownBy(() -> cms.create(regionConfig)).hasMessageContaining("ILLEGAL_ARGUMENT");
 
     regionConfig.setName("incompatible");
     regionConfig.setGroup("group5");
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 3df9c2b..f5c7cd2 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -677,12 +677,14 @@ javadoc/org/apache/geode/management/PersistentMemberDetails.html
 javadoc/org/apache/geode/management/RegionAttributesData.html
 javadoc/org/apache/geode/management/RegionMXBean.html
 javadoc/org/apache/geode/management/ServerLoadData.html
+javadoc/org/apache/geode/management/api/ClusterManagementException.html
 javadoc/org/apache/geode/management/api/ClusterManagementListOperationsResult.html
 javadoc/org/apache/geode/management/api/ClusterManagementListResult.html
 javadoc/org/apache/geode/management/api/ClusterManagementOperation.html
 javadoc/org/apache/geode/management/api/ClusterManagementOperationResult.html
 javadoc/org/apache/geode/management/api/ClusterManagementResult.StatusCode.html
 javadoc/org/apache/geode/management/api/ClusterManagementResult.html
+javadoc/org/apache/geode/management/api/ClusterManagementRealizationException.html
 javadoc/org/apache/geode/management/api/ClusterManagementRealizationResult.html
 javadoc/org/apache/geode/management/api/ClusterManagementService.html
 javadoc/org/apache/geode/management/api/ConfigurationResult.html
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
index fc84820..b5a2761 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
@@ -68,6 +68,8 @@ org/apache/geode/internal/shared/TCPSocketOptions
 org/apache/geode/internal/statistics/platform/LinuxProcFsStatistics$CPU
 org/apache/geode/internal/tcp/VersionedByteBufferInputStream
 org/apache/geode/internal/util/concurrent/StoppableReadWriteLock
+org/apache/geode/management/api/ClusterManagementException
+org/apache/geode/management/api/ClusterManagementRealizationException
 org/apache/geode/management/internal/cli/commands/ShowMetricsCommand$Category
 org/apache/geode/management/internal/cli/exceptions/UserErrorException
 org/apache/geode/management/internal/cli/json/AbstractJSONFormatter$PreventReserializationModule
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 d96d0c3..9dd5619 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
@@ -17,6 +17,11 @@
 
 package org.apache.geode.management.internal.api;
 
+import static org.apache.geode.management.api.ClusterManagementResult.StatusCode.ENTITY_EXISTS;
+import static org.apache.geode.management.api.ClusterManagementResult.StatusCode.ENTITY_NOT_FOUND;
+import static org.apache.geode.management.api.ClusterManagementResult.StatusCode.ERROR;
+import static org.apache.geode.management.api.ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -46,10 +51,12 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.execute.AbstractExecution;
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.api.ClusterManagementException;
 import org.apache.geode.management.api.ClusterManagementListOperationsResult;
 import org.apache.geode.management.api.ClusterManagementListResult;
 import org.apache.geode.management.api.ClusterManagementOperation;
 import org.apache.geode.management.api.ClusterManagementOperationResult;
+import org.apache.geode.management.api.ClusterManagementRealizationException;
 import org.apache.geode.management.api.ClusterManagementRealizationResult;
 import org.apache.geode.management.api.ClusterManagementResult;
 import org.apache.geode.management.api.ClusterManagementResult.StatusCode;
@@ -72,7 +79,7 @@ import org.apache.geode.management.internal.configuration.validators.Configurati
 import org.apache.geode.management.internal.configuration.validators.GatewayReceiverConfigValidator;
 import org.apache.geode.management.internal.configuration.validators.MemberValidator;
 import org.apache.geode.management.internal.configuration.validators.RegionConfigValidator;
-import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
+import org.apache.geode.management.internal.exceptions.EntityExistsException;
 import org.apache.geode.management.internal.operation.OperationHistoryManager;
 import org.apache.geode.management.internal.operation.OperationHistoryManager.OperationInstance;
 import org.apache.geode.management.internal.operation.OperationManager;
@@ -125,25 +132,30 @@ public class LocatorClusterManagementService implements ClusterManagementService
     ConfigurationManager configurationManager = getConfigurationManager(config);
 
     if (persistenceService == null) {
-      return new ClusterManagementRealizationResult(false,
-          "Cluster configuration service needs to be enabled");
+      return assertSuccessful(new ClusterManagementRealizationResult(false,
+          "Cluster configuration service needs to be enabled"));
     }
 
-    // first validate common attributes of all configuration object
-    commonValidator.validate(CacheElementOperation.CREATE, config);
-
     String group = config.getConfigGroup();
-    ConfigurationValidator validator = validators.get(config.getClass());
-    if (validator != null) {
-      validator.validate(CacheElementOperation.CREATE, config);
-    }
+    try {
+      // first validate common attributes of all configuration object
+      commonValidator.validate(CacheElementOperation.CREATE, config);
 
-    // check if this config already exists on all/some members of this group
-    memberValidator.validateCreate(config, configurationManager);
+      ConfigurationValidator validator = validators.get(config.getClass());
+      if (validator != null) {
+        validator.validate(CacheElementOperation.CREATE, config);
+      }
 
-    // execute function on all members
-    Set<DistributedMember> targetedMembers = memberValidator.findServers(group);
+      // check if this config already exists on all/some members of this group
+      memberValidator.validateCreate(config, configurationManager);
+      // execute function on all members
+    } catch (EntityExistsException e) {
+      raise(ENTITY_EXISTS, e);
+    } catch (IllegalArgumentException e) {
+      raise(ILLEGAL_ARGUMENT, e);
+    }
 
+    Set<DistributedMember> targetedMembers = memberValidator.findServers(group);
     ClusterManagementRealizationResult result = new ClusterManagementRealizationResult();
 
     List<RealizationResult> functionResults = executeAndGetFunctionResult(
@@ -156,7 +168,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
     // if any false result is added to the member list
     if (result.getStatusCode() != StatusCode.OK) {
       result.setStatus(false, "Failed to apply the update on all members");
-      return result;
+      return assertSuccessful(result);
     }
 
     // persist configuration in cache config
@@ -179,7 +191,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
     if (result.isSuccessful() && config instanceof RestfulEndpoint) {
       result.setUri(((RestfulEndpoint) config).getUri());
     }
-    return result;
+    return assertSuccessful(result);
   }
 
   @Override
@@ -189,22 +201,26 @@ public class LocatorClusterManagementService implements ClusterManagementService
     ConfigurationManager configurationManager = getConfigurationManager(config);
 
     if (persistenceService == null) {
-      return new ClusterManagementRealizationResult(false,
-          "Cluster configuration service needs to be enabled");
+      return assertSuccessful(new ClusterManagementRealizationResult(false,
+          "Cluster configuration service needs to be enabled"));
     }
 
-    // first validate common attributes of all configuration object
-    commonValidator.validate(CacheElementOperation.DELETE, config);
+    try {
+      // first validate common attributes of all configuration object
+      commonValidator.validate(CacheElementOperation.DELETE, config);
 
-    ConfigurationValidator validator = validators.get(config.getClass());
-    if (validator != null) {
-      validator.validate(CacheElementOperation.DELETE, config);
+      ConfigurationValidator validator = validators.get(config.getClass());
+      if (validator != null) {
+        validator.validate(CacheElementOperation.DELETE, config);
+      }
+    } catch (IllegalArgumentException e) {
+      raise(ILLEGAL_ARGUMENT, e);
     }
 
     String[] groupsWithThisElement =
         memberValidator.findGroupsWithThisElement(config.getId(), configurationManager);
     if (groupsWithThisElement.length == 0) {
-      throw new EntityNotFoundException("Cache element '" + config.getId() + "' does not exist");
+      raise(ENTITY_NOT_FOUND, "Cache element '" + config.getId() + "' does not exist");
     }
 
     // execute function on all members
@@ -246,7 +262,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
       result.setStatus(StatusCode.FAIL_TO_PERSIST, message);
     }
 
-    return result;
+    return assertSuccessful(result);
   }
 
   @Override
@@ -261,8 +277,8 @@ public class LocatorClusterManagementService implements ClusterManagementService
     ClusterManagementListResult<T, R> result = new ClusterManagementListResult<>();
 
     if (persistenceService == null) {
-      return new ClusterManagementListResult<>(false,
-          "Cluster configuration service needs to be enabled");
+      return assertSuccessful(new ClusterManagementListResult<>(false,
+          "Cluster configuration service needs to be enabled"));
     }
 
     List<T> resultList = new ArrayList<>();
@@ -355,7 +371,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
     }
 
     result.setResult(responses);
-    return result;
+    return assertSuccessful(result);
   }
 
   @Override
@@ -365,22 +381,20 @@ public class LocatorClusterManagementService implements ClusterManagementService
     List<ConfigurationResult<T, R>> result = list.getResult();
 
     if (result.size() == 0) {
-      throw new EntityNotFoundException(
+      raise(ENTITY_NOT_FOUND,
           config.getClass().getSimpleName() + " with id = " + config.getId() + " not found.");
     }
 
     if (result.size() > 1) {
-      throw new IllegalStateException(
-          "Expect only one matching " + config.getClass().getSimpleName());
+      raise(ERROR, "Expect only one matching " + config.getClass().getSimpleName());
     }
-    return list;
+    return assertSuccessful(list);
   }
 
   @Override
   public <A extends ClusterManagementOperation<V>, V extends OperationResult> ClusterManagementOperationResult<V> start(
       A op) {
     OperationInstance<A, V> operationInstance = operationManager.submit(op);
-    CompletableFuture<V> future = operationInstance.getFutureResult();
     if (op instanceof TaggedWithOperator) {
       operationInstance.setOperator(((TaggedWithOperator) op).getOperator());
     }
@@ -389,15 +403,15 @@ public class LocatorClusterManagementService implements ClusterManagementService
         StatusCode.ACCEPTED,
         "async operation started (GET uri to check status)");
 
-    return toClusterManagementListOperationsResult(result, operationInstance);
+    return assertSuccessful(toClusterManagementListOperationsResult(result, operationInstance));
   }
 
   @Override
   public <A extends ClusterManagementOperation<V>, V extends OperationResult> ClusterManagementListOperationsResult<V> list(
       A opType) {
-    return new ClusterManagementListOperationsResult<>(
+    return assertSuccessful(new ClusterManagementListOperationsResult<>(
         operationManager.listOperationInstances(opType).stream()
-            .map(this::toClusterManagementListOperationsResult).collect(Collectors.toList()));
+            .map(this::toClusterManagementListOperationsResult).collect(Collectors.toList())));
   }
 
   /**
@@ -444,7 +458,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
       String opId) {
     final OperationInstance<?, V> operationInstance = operationManager.getOperationInstance(opId);
     if (operationInstance == null) {
-      throw new EntityNotFoundException("Operation id = " + opId + " not found");
+      raise(ENTITY_NOT_FOUND, "Operation id = " + opId + " not found");
     }
     final CompletableFuture<V> status = operationInstance.getFutureResult();
     ClusterManagementOperationStatusResult<V> result =
@@ -468,7 +482,27 @@ public class LocatorClusterManagementService implements ClusterManagementService
     return result;
   }
 
-  @Override
+  private <T extends ClusterManagementResult> T assertSuccessful(T result) {
+    if (!result.isSuccessful()) {
+      if (result instanceof ClusterManagementRealizationResult) {
+        throw new ClusterManagementRealizationException(
+            (ClusterManagementRealizationResult) result);
+      } else {
+        throw new ClusterManagementException(result);
+      }
+    }
+    return result;
+  }
+
+  private static void raise(StatusCode statusCode, String statusMessage) {
+    throw new ClusterManagementException(new ClusterManagementResult(statusCode, statusMessage));
+  }
+
+  private static void raise(StatusCode statusCode, Exception e) {
+    throw new ClusterManagementException(new ClusterManagementResult(statusCode, e.getMessage()),
+        e);
+  }
+
   public boolean isConnected() {
     return true;
   }
@@ -482,7 +516,7 @@ public class LocatorClusterManagementService implements ClusterManagementService
       T config) {
     ConfigurationManager configurationManager = managers.get(config.getClass());
     if (configurationManager == null) {
-      throw new IllegalArgumentException(String.format("Configuration type %s is not supported",
+      raise(ILLEGAL_ARGUMENT, String.format("Configuration type %s is not supported",
           config.getClass().getSimpleName()));
     }
 
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
index f31f20e..a8bf6f8 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/api/LocatorClusterManagementServiceTest.java
@@ -53,6 +53,7 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.config.JAXBService;
+import org.apache.geode.management.api.ClusterManagementException;
 import org.apache.geode.management.api.ClusterManagementOperation;
 import org.apache.geode.management.api.ClusterManagementOperationResult;
 import org.apache.geode.management.api.ClusterManagementRealizationResult;
@@ -68,7 +69,6 @@ import org.apache.geode.management.internal.configuration.validators.CacheElemen
 import org.apache.geode.management.internal.configuration.validators.ConfigurationValidator;
 import org.apache.geode.management.internal.configuration.validators.MemberValidator;
 import org.apache.geode.management.internal.configuration.validators.RegionConfigValidator;
-import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
 import org.apache.geode.management.internal.operation.OperationHistoryManager.OperationInstance;
 import org.apache.geode.management.internal.operation.OperationManager;
 import org.apache.geode.management.runtime.OperationResult;
@@ -119,16 +119,14 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void create_persistenceIsNull() throws Exception {
+  public void create_persistenceIsNull() {
     service = new LocatorClusterManagementService(cache, null);
-    result = service.create(regionConfig);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusMessage())
-        .contains("Cluster configuration service needs to be enabled");
+    assertThatThrownBy(() -> service.create(regionConfig))
+        .hasMessageContaining("Cluster configuration service needs to be enabled");
   }
 
   @Test
-  public void create_validatorIsCalledCorrectly() throws Exception {
+  public void create_validatorIsCalledCorrectly() {
     doReturn(Collections.emptySet()).when(memberValidator).findServers(anyString());
     doNothing().when(persistenceService).updateCacheConfig(any(), any());
     service.create(regionConfig);
@@ -138,7 +136,7 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void delete_validatorIsCalledCorrectly() throws Exception {
+  public void delete_validatorIsCalledCorrectly() {
     doReturn(Collections.emptySet()).when(memberValidator).findServers(anyString());
     doReturn(new String[] {"cluster"}).when(memberValidator).findGroupsWithThisElement(
         regionConfig.getId(),
@@ -152,7 +150,7 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void create_partialFailureOnMembers() throws Exception {
+  public void create_partialFailureOnMembers() {
     List<RealizationResult> functionResults = new ArrayList<>();
     functionResults.add(new RealizationResult().setMemberName("member1"));
     functionResults.add(
@@ -164,14 +162,12 @@ public class LocatorClusterManagementServiceTest {
 
     when(persistenceService.getCacheConfig("cluster", true)).thenReturn(new CacheConfig());
     regionConfig.setName("test");
-    result = service.create(regionConfig);
-    assertThat(result.isSuccessful()).isFalse();
-    assertThat(result.getStatusMessage())
-        .contains("Failed to apply the update on all members");
+    assertThatThrownBy(() -> service.create(regionConfig))
+        .hasMessageContaining("Failed to apply the update on all members");
   }
 
   @Test
-  public void create_succeedsOnAllMembers() throws Exception {
+  public void create_succeedsOnAllMembers() {
     List<RealizationResult> functionResults = new ArrayList<>();
     functionResults.add(new RealizationResult().setMemberName("member1"));
     functionResults.add(new RealizationResult().setMemberName("member2"));
@@ -194,14 +190,14 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void create_non_supportedConfigObject() throws Exception {
+  public void create_non_supportedConfigObject() {
     MemberConfig config = new MemberConfig();
-    assertThatThrownBy(() -> service.create(config)).isInstanceOf(IllegalArgumentException.class)
-        .hasMessageContaining("Configuration type MemberConfig is not supported");
+    assertThatThrownBy(() -> service.create(config)).isInstanceOf(ClusterManagementException.class)
+        .hasMessageContaining("ILLEGAL_ARGUMENT: Configuration type MemberConfig is not supported");
   }
 
   @Test
-  public void list_oneGroup() throws Exception {
+  public void list_oneGroup() {
     regionConfig.setGroup("cluster");
     doReturn(Sets.newHashSet("cluster", "group1")).when(persistenceService).getGroups();
 
@@ -213,7 +209,7 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void list_aRegionInClusterAndGroup1() throws Exception {
+  public void list_aRegionInClusterAndGroup1() {
     doReturn(Sets.newHashSet("cluster", "group1")).when(persistenceService).getGroups();
     RegionConfig region1 = new RegionConfig();
     region1.setName("region1");
@@ -242,8 +238,8 @@ public class LocatorClusterManagementServiceTest {
     config.setName("unknown");
     doReturn(new String[] {}).when(memberValidator).findGroupsWithThisElement(any(), any());
     assertThatThrownBy(() -> service.delete(config))
-        .isInstanceOf(EntityNotFoundException.class)
-        .hasMessage("Cache element 'unknown' does not exist");
+        .isInstanceOf(ClusterManagementException.class)
+        .hasMessage("ENTITY_NOT_FOUND: Cache element 'unknown' does not exist");
   }
 
   @Test
@@ -252,12 +248,12 @@ public class LocatorClusterManagementServiceTest {
     config.setName("test");
     config.setGroup("group1");
     assertThatThrownBy(() -> service.delete(config))
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessage("group is an invalid option when deleting region.");
+        .isInstanceOf(ClusterManagementException.class)
+        .hasMessage("ILLEGAL_ARGUMENT: group is an invalid option when deleting region.");
   }
 
   @Test
-  public void delete_partialFailureOnMembers() throws Exception {
+  public void delete_partialFailureOnMembers() {
     List<RealizationResult> functionResults = new ArrayList<>();
     functionResults.add(new RealizationResult().setMemberName("member1"));
     functionResults.add(
@@ -284,7 +280,7 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void delete_succeedsOnAllMembers() throws Exception {
+  public void delete_succeedsOnAllMembers() {
     List<RealizationResult> functionResults = new ArrayList<>();
     functionResults.add(new RealizationResult().setMemberName("member1"));
     functionResults.add(new RealizationResult().setMemberName("member2"));
@@ -311,7 +307,7 @@ public class LocatorClusterManagementServiceTest {
   }
 
   @Test
-  public void deleteWithNoMember() throws Exception {
+  public void deleteWithNoMember() {
     // region exists in cluster configuration
     doReturn(new String[] {"cluster"}).when(memberValidator).findGroupsWithThisElement(any(),
         any());
@@ -344,7 +340,7 @@ public class LocatorClusterManagementServiceTest {
   @Test
   public void checkStatusForNotFound() {
     assertThatThrownBy(() -> service.checkStatus("123"))
-        .isInstanceOf(EntityNotFoundException.class);
+        .isInstanceOf(ClusterManagementException.class);
   }
 
   @Test
diff --git a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementException.java b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementException.java
new file mode 100644
index 0000000..1c57767
--- /dev/null
+++ b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementException.java
@@ -0,0 +1,60 @@
+/*
+ * 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.api;
+
+
+/**
+ * Base class of all exceptions thrown by {@link ClusterManagementService} implementations.
+ */
+public class ClusterManagementException extends RuntimeException {
+  private final ClusterManagementResult result;
+
+  /**
+   * for internal use only
+   */
+  public ClusterManagementException(ClusterManagementResult result) {
+    super(result.toString());
+    this.result = result;
+  }
+
+  /**
+   * for internal use only
+   */
+  public ClusterManagementException(ClusterManagementResult result, Throwable cause) {
+    super(result.toString(), cause);
+    this.result = result;
+  }
+
+  /**
+   * for internal use only
+   */
+  public ClusterManagementResult getResult() {
+    return result;
+  }
+
+  /**
+   * get the status code of the unsuccessful result
+   */
+  public ClusterManagementResult.StatusCode getStatusCode() {
+    return result.getStatusCode();
+  }
+
+  /**
+   * get the status message of the unsuccessful result, if available
+   */
+  public String getStatusMessage() {
+    return result.getStatusMessage();
+  }
+}
diff --git a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementRealizationException.java b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementRealizationException.java
new file mode 100644
index 0000000..728fc45
--- /dev/null
+++ b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementRealizationException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.api;
+
+import java.util.List;
+
+import org.apache.geode.cache.configuration.CacheElement;
+
+/**
+ * Thrown by {@link ClusterManagementService#create(CacheElement)}, update, and delete operations
+ * which have a possibility of "partial" failure.
+ */
+public class ClusterManagementRealizationException extends ClusterManagementException {
+  private final ClusterManagementRealizationResult result;
+
+  /**
+   * for internal use only
+   */
+  public ClusterManagementRealizationException(ClusterManagementRealizationResult result) {
+    super(result);
+    this.result = result;
+  }
+
+  /**
+   * A {@link ClusterManagementService#create(CacheElement)} operation may fail on all members or
+   * only some. This will return the per-member status.
+   */
+  public List<RealizationResult> getMemberStatuses() {
+    return result.getMemberStatuses();
+  }
+}
diff --git a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
index 51f710f..e0a770d 100644
--- a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
+++ b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementResult.java
@@ -14,6 +14,8 @@
  */
 package org.apache.geode.management.api;
 
+import static org.apache.commons.lang3.StringUtils.isBlank;
+
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
 import org.apache.geode.annotations.Experimental;
@@ -147,4 +149,16 @@ public class ClusterManagementResult {
   public StatusCode getStatusCode() {
     return statusCode;
   }
+
+  /**
+   * Returns the status code and message
+   */
+  @Override
+  public String toString() {
+    if (isBlank(getStatusMessage())) {
+      return getStatusCode().toString();
+    } else {
+      return getStatusCode() + ": " + getStatusMessage();
+    }
+  }
 }
diff --git a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
index 8360621..663f320 100644
--- a/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
+++ b/geode-management/src/main/java/org/apache/geode/management/api/ClusterManagementService.java
@@ -35,6 +35,7 @@ public interface ClusterManagementService extends AutoCloseable {
    * @param config this holds the configuration attributes of the element to be created on the
    *        cluster, as well as the group this config belongs to
    * @return a {@link ClusterManagementRealizationResult} indicating the success of the creation
+   * @throws ClusterManagementRealizationException if unsuccessful
    * @see CacheElement
    */
   <T extends CacheElement> ClusterManagementRealizationResult create(T config);
@@ -46,7 +47,7 @@ public interface ClusterManagementService extends AutoCloseable {
    * @param config this holds the configuration attributes of the element to be deleted on the
    *        cluster
    * @return a {@link ClusterManagementRealizationResult} indicating the success of the deletion
-   * @throws IllegalArgumentException, NoMemberException, EntityExistsException
+   * @throws ClusterManagementRealizationException if unsuccessful
    * @see CacheElement
    */
   <T extends CacheElement> ClusterManagementRealizationResult delete(T config);
@@ -58,7 +59,7 @@ public interface ClusterManagementService extends AutoCloseable {
    * @param config this holds the configuration attributes of the element to be updated on the
    *        cluster
    * @return a {@link ClusterManagementRealizationResult} indicating the success of the update
-   * @throws IllegalArgumentException, NoMemberException, EntityExistsException
+   * @throws ClusterManagementRealizationException if unsuccessful
    * @see CacheElement
    */
   <T extends CacheElement> ClusterManagementRealizationResult update(T config);
@@ -71,6 +72,7 @@ public interface ClusterManagementService extends AutoCloseable {
    *        for individual element types to see if they support filtering by addition attributes)
    * @return a {@link ClusterManagementListResult} holding a list of matching instances in
    *         {@link ClusterManagementListResult#getResult()}
+   * @throws ClusterManagementException if unsuccessful
    * @see CacheElement
    */
   <T extends CacheElement & CorrespondWith<R>, R extends RuntimeInfo> ClusterManagementListResult<T, R> list(
@@ -84,7 +86,8 @@ public interface ClusterManagementService extends AutoCloseable {
    *        supplying the name (id) of the desired config element
    * @return a {@link ClusterManagementListResult} holding a single element in
    *         {@link ClusterManagementListResult#getResult()}
-   * @throws RuntimeException if no matching element is found or multiple matches are found
+   * @throws ClusterManagementException if unsuccesful or, no matching element is found, or multiple
+   *         matches are found
    * @see CacheElement
    */
   <T extends CacheElement & CorrespondWith<R>, R extends RuntimeInfo> ClusterManagementListResult<T, R> get(
@@ -98,6 +101,7 @@ public interface ClusterManagementService extends AutoCloseable {
    * @param <V> the return type of the operation
    * @return a {@link ClusterManagementOperationResult} holding a {@link CompletableFuture} (if the
    *         operation was launched successfully) or an error code otherwise.
+   * @throws ClusterManagementException if unsuccessful
    */
   <A extends ClusterManagementOperation<V>, V extends OperationResult> ClusterManagementOperationResult<V> start(
       A op);
@@ -110,6 +114,7 @@ public interface ClusterManagementService extends AutoCloseable {
    * @param <V> the return type of the operation
    * @param opType the operation type to list
    * @return a list of {@link ClusterManagementOperationResult}
+   * @throws ClusterManagementException if unsuccessful
    */
   <A extends ClusterManagementOperation<V>, V extends OperationResult> ClusterManagementListOperationsResult<V> list(
       A opType);
diff --git a/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java b/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
index 7835c37..27d7df3 100644
--- a/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
+++ b/geode-management/src/main/java/org/apache/geode/management/internal/ClientClusterManagementService.java
@@ -27,6 +27,7 @@ import org.springframework.http.HttpMethod;
 import org.springframework.web.client.RestTemplate;
 
 import org.apache.geode.cache.configuration.CacheElement;
+import org.apache.geode.management.api.ClusterManagementException;
 import org.apache.geode.management.api.ClusterManagementListOperationsResult;
 import org.apache.geode.management.api.ClusterManagementListResult;
 import org.apache.geode.management.api.ClusterManagementOperation;
@@ -72,9 +73,9 @@ public class ClientClusterManagementService implements ClusterManagementService
   public <T extends CacheElement> ClusterManagementRealizationResult create(T config) {
     String endPoint = getEndpoint(config);
     // the response status code info is represented by the ClusterManagementResult.errorCode already
-    return restTemplate
+    return assertSuccessful(restTemplate
         .postForEntity(endPoint, config, ClusterManagementRealizationResult.class)
-        .getBody();
+        .getBody());
   }
 
   @Override
@@ -82,13 +83,13 @@ public class ClientClusterManagementService implements ClusterManagementService
   public <T extends CacheElement> ClusterManagementRealizationResult delete(
       T config) {
     String uri = getIdentityEndPoint(config);
-    return restTemplate
+    return assertSuccessful(restTemplate
         .exchange(uri + "?group={group}",
             HttpMethod.DELETE,
             null,
             ClusterManagementRealizationResult.class,
             config.getGroup())
-        .getBody();
+        .getBody());
   }
 
   @Override
@@ -102,19 +103,19 @@ public class ClientClusterManagementService implements ClusterManagementService
   public <T extends CacheElement & CorrespondWith<R>, R extends RuntimeInfo> ClusterManagementListResult<T, R> list(
       T config) {
     String endPoint = getEndpoint(config);
-    return restTemplate
+    return assertSuccessful(restTemplate
         .getForEntity(endPoint + "/?id={id}&group={group}",
             ClusterManagementListResult.class, config.getId(), config.getGroup())
-        .getBody();
+        .getBody());
   }
 
   @Override
   @SuppressWarnings("unchecked")
   public <T extends CacheElement & CorrespondWith<R>, R extends RuntimeInfo> ClusterManagementListResult<T, R> get(
       T config) {
-    return restTemplate
+    return assertSuccessful(restTemplate
         .getForEntity(getIdentityEndPoint(config), ClusterManagementListResult.class)
-        .getBody();
+        .getBody());
   }
 
   @Override
@@ -124,8 +125,9 @@ public class ClientClusterManagementService implements ClusterManagementService
     final ClusterManagementOperationResult result;
 
     // make the REST call to start the operation
-    result = restTemplate.postForEntity(RestfulEndpoint.URI_VERSION + op.getEndpoint(), op,
-        ClusterManagementOperationResult.class).getBody();
+    result =
+        assertSuccessful(restTemplate.postForEntity(RestfulEndpoint.URI_VERSION + op.getEndpoint(),
+            op, ClusterManagementOperationResult.class).getBody());
 
     // our restTemplate requires the url to be modified to start from "/experimental"
     return reAnimate(result);
@@ -152,8 +154,9 @@ public class ClientClusterManagementService implements ClusterManagementService
     final ClusterManagementListOperationsResult<V> result;
 
     // make the REST call to list in-progress operations
-    result = restTemplate.getForEntity(RestfulEndpoint.URI_VERSION + opType.getEndpoint(),
-        ClusterManagementListOperationsResult.class).getBody();
+    result = assertSuccessful(
+        restTemplate.getForEntity(RestfulEndpoint.URI_VERSION + opType.getEndpoint(),
+            ClusterManagementListOperationsResult.class).getBody());
 
     return new ClusterManagementListOperationsResult<>(
         result.getResult().stream().map(this::reAnimate).collect(Collectors.toList()));
@@ -194,9 +197,20 @@ public class ClientClusterManagementService implements ClusterManagementService
     }
   }
 
+  private <T extends ClusterManagementResult> T assertSuccessful(T result) {
+    if (!result.isSuccessful()) {
+      throw new ClusterManagementException(result);
+    }
+    return result;
+  }
+
   public boolean isConnected() {
-    return restTemplate.getForEntity(RestfulEndpoint.URI_VERSION + "/ping", String.class)
-        .getBody().equals("pong");
+    try {
+      return restTemplate.getForEntity(RestfulEndpoint.URI_VERSION + "/ping", String.class)
+          .getBody().equals("pong");
+    } catch (Exception e) {
+      return false;
+    }
   }
 
   @Override
diff --git a/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java b/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
index 8b98e85..25bfc25 100644
--- a/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
+++ b/geode-web-management/src/distributedTest/java/org/apache/geode/management/client/ClientClusterManagementServiceDUnitTest.java
@@ -18,6 +18,7 @@ package org.apache.geode.management.client;
 import static org.apache.geode.test.junit.assertions.ClusterManagementListResultAssert.assertManagementListResult;
 import static org.apache.geode.test.junit.assertions.ClusterManagementRealizationResultAssert.assertManagementResult;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.List;
 
@@ -149,9 +150,8 @@ public class ClientClusterManagementServiceDUnitTest {
 
     // creating the same region on group2 will not be successful because they have a common member
     region.setGroup("group2");
-    assertManagementResult(client.create(region)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ENTITY_EXISTS)
-        .containsStatusMessage("Member(s) server-3 already has this element created");
+    assertThatThrownBy(() -> client.create(region))
+        .hasMessageContaining("ENTITY_EXISTS: Member(s) server-3 already has this element created");
   }
 
   @Test
@@ -170,8 +170,7 @@ public class ClientClusterManagementServiceDUnitTest {
 
     // creating the same region on group2 will not be successful because they have a common member
     region.setGroup("group2");
-    assertManagementResult(client.create(region)).failed().hasStatusCode(
-        ClusterManagementResult.StatusCode.ENTITY_EXISTS);
+    assertThatThrownBy(() -> client.create(region)).hasMessageContaining("ENTITY_EXISTS");
 
     region.setGroup(null);
     ClusterManagementRealizationResult deleteResult = client.delete(region);
@@ -198,9 +197,8 @@ public class ClientClusterManagementServiceDUnitTest {
         .extracting(RealizationResult::getMemberName)
         .containsExactlyInAnyOrder("server-1", "server-3");
 
-    assertManagementResult(client.delete(region)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
-        .containsStatusMessage("group is an invalid option when deleting region");
+    assertThatThrownBy(() -> client.delete(region))
+        .hasMessageContaining("ILLEGAL_ARGUMENT: group is an invalid option when deleting region");
   }
 
   @Test
@@ -209,9 +207,7 @@ public class ClientClusterManagementServiceDUnitTest {
     RegionConfig region = new RegionConfig();
     region.setName("unknown");
 
-    ClusterManagementRealizationResult result = client.delete(region);
-    assertManagementResult(result).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ENTITY_NOT_FOUND);
+    assertThatThrownBy(() -> client.delete(region)).hasMessageContaining("ENTITY_NOT_FOUND");
   }
 
   @Test
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
index 85e1ed8..fe79a6c 100644
--- 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
@@ -16,7 +16,7 @@
 package org.apache.geode.management.internal.rest;
 
 
-import static org.apache.geode.test.junit.assertions.ClusterManagementRealizationResultAssert.assertManagementResult;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 
 import java.util.List;
@@ -33,7 +33,6 @@ import org.springframework.web.context.WebApplicationContext;
 import org.apache.geode.cache.configuration.GatewayReceiverConfig;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.management.api.ClusterManagementListResult;
-import org.apache.geode.management.api.ClusterManagementResult;
 import org.apache.geode.management.api.ClusterManagementService;
 import org.apache.geode.management.api.ConfigurationResult;
 import org.apache.geode.management.client.ClusterManagementServiceBuilder;
@@ -110,16 +109,12 @@ public class GatewayManagementIntegrationTest {
   @Test
   public void createWithBindAddress() throws Exception {
     receiver.setBindAddress("test-mbpro");
-    assertManagementResult(client.create(receiver)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
-        .containsStatusMessage("");
+    assertThatThrownBy(() -> client.create(receiver)).hasMessageContaining("ILLEGAL_ARGUMENT");
   }
 
   @Test
   public void createWithHostName() throws Exception {
     receiver.setHostnameForSenders("test-mbpro");
-    assertManagementResult(client.create(receiver)).failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
-        .containsStatusMessage("");
+    assertThatThrownBy(() -> client.create(receiver)).hasMessageContaining("ILLEGAL_ARGUMENT");
   }
 }
diff --git a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
index bb44ba9..1df988c 100644
--- a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
+++ b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java
@@ -16,6 +16,7 @@
 package org.apache.geode.management.internal.rest;
 
 import static org.apache.geode.test.junit.assertions.ClusterManagementRealizationResultAssert.assertManagementResult;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
 
@@ -58,7 +59,7 @@ public class RegionManagementIntegrationTest {
 
   @Test
   @WithMockUser
-  public void sanityCheck() throws Exception {
+  public void sanityCheck() {
     RegionConfig regionConfig = new RegionConfig();
     regionConfig.setName("customers");
     regionConfig.setType(RegionType.REPLICATE);
@@ -71,27 +72,24 @@ public class RegionManagementIntegrationTest {
 
   @Test
   @WithMockUser
-  public void invalidType() throws Exception {
+  public void invalidType() {
     RegionConfig regionConfig = new RegionConfig();
     regionConfig.setName("customers");
     regionConfig.setType("LOCAL");
 
-    assertManagementResult(client.create(regionConfig))
-        .failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
-        .containsStatusMessage("Type LOCAL is not supported in Management V2 API.");
+    assertThatThrownBy(() -> client.create(regionConfig))
+        .hasMessageContaining(
+            "ILLEGAL_ARGUMENT: Type LOCAL is not supported in Management V2 API.");
   }
 
   @Test
-  public void invalidGroup() throws Exception {
+  public void invalidGroup() {
     RegionConfig regionConfig = new RegionConfig();
     regionConfig.setName("customers");
     regionConfig.setGroup("cluster");
 
-    assertManagementResult(client.create(regionConfig))
-        .failed()
-        .hasStatusCode(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT)
-        .containsStatusMessage("'cluster' is a reserved group name");
+    assertThatThrownBy(() -> client.create(regionConfig))
+        .hasMessageContaining("ILLEGAL_ARGUMENT: 'cluster' is a reserved group name");
   }
 
   @Test
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/ManagementControllerAdvice.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/ManagementControllerAdvice.java
index d97a533..9e6b526 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/ManagementControllerAdvice.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/ManagementControllerAdvice.java
@@ -14,7 +14,6 @@
  */
 package org.apache.geode.management.internal.rest.controllers;
 
-
 import org.apache.logging.log4j.Logger;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -25,9 +24,11 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.api.ClusterManagementException;
+import org.apache.geode.management.api.ClusterManagementRealizationException;
+import org.apache.geode.management.api.ClusterManagementRealizationResult;
 import org.apache.geode.management.api.ClusterManagementResult;
-import org.apache.geode.management.internal.exceptions.EntityExistsException;
-import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
+import org.apache.geode.management.api.ClusterManagementResult.StatusCode;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.NotAuthorizedException;
 
@@ -39,7 +40,7 @@ public class ManagementControllerAdvice {
   public ResponseEntity<ClusterManagementResult> internalError(final Exception e) {
     logger.error(e.getMessage(), e);
     return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.ERROR,
+        new ClusterManagementResult(StatusCode.ERROR,
             cleanup(e.getMessage())),
         HttpStatus.INTERNAL_SERVER_ERROR);
   }
@@ -54,26 +55,37 @@ public class ManagementControllerAdvice {
     }
   }
 
-  @ExceptionHandler(EntityExistsException.class)
-  public ResponseEntity<ClusterManagementResult> entityExists(final Exception e) {
-    return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.ENTITY_EXISTS,
-            e.getMessage()),
-        HttpStatus.CONFLICT);
+  @ExceptionHandler(ClusterManagementException.class)
+  public ResponseEntity<ClusterManagementResult> clusterManagementException(final Exception e) {
+    ClusterManagementResult result = ((ClusterManagementException) e).getResult();
+    return new ResponseEntity<>(result, mapToHttpStatus(result.getStatusCode()));
   }
 
-  @ExceptionHandler(EntityNotFoundException.class)
-  public ResponseEntity<ClusterManagementResult> entityNotFound(final Exception e) {
-    return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.ENTITY_NOT_FOUND,
-            e.getMessage()),
-        HttpStatus.NOT_FOUND);
+  @ExceptionHandler(ClusterManagementRealizationException.class)
+  public ResponseEntity<ClusterManagementRealizationResult> clusterManagementRealizationException(
+      final Exception e) {
+    ClusterManagementRealizationResult result =
+        (ClusterManagementRealizationResult) ((ClusterManagementException) e).getResult();
+    return new ResponseEntity<>(result, mapToHttpStatus(result.getStatusCode()));
+  }
+
+  private HttpStatus mapToHttpStatus(StatusCode statusCode) {
+    switch (statusCode) {
+      case ENTITY_EXISTS:
+        return HttpStatus.CONFLICT;
+      case ENTITY_NOT_FOUND:
+        return HttpStatus.NOT_FOUND;
+      case ILLEGAL_ARGUMENT:
+        return HttpStatus.BAD_REQUEST;
+      default:
+        return HttpStatus.INTERNAL_SERVER_ERROR;
+    }
   }
 
   @ExceptionHandler({AuthenticationFailedException.class, AuthenticationException.class})
   public ResponseEntity<ClusterManagementResult> unauthorized(Exception e) {
     return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.UNAUTHENTICATED,
+        new ClusterManagementResult(StatusCode.UNAUTHENTICATED,
             e.getMessage()),
         HttpStatus.UNAUTHORIZED);
   }
@@ -81,19 +93,18 @@ public class ManagementControllerAdvice {
   @ExceptionHandler({NotAuthorizedException.class, SecurityException.class})
   public ResponseEntity<ClusterManagementResult> forbidden(Exception e) {
     return new ResponseEntity<>(new ClusterManagementResult(
-        ClusterManagementResult.StatusCode.UNAUTHORIZED, e.getMessage()),
+        StatusCode.UNAUTHORIZED, e.getMessage()),
         HttpStatus.FORBIDDEN);
   }
 
   @ExceptionHandler({IllegalArgumentException.class, HttpMessageNotReadableException.class})
   public ResponseEntity<ClusterManagementResult> badRequest(final Exception e) {
     return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.ILLEGAL_ARGUMENT,
+        new ClusterManagementResult(StatusCode.ILLEGAL_ARGUMENT,
             e.getMessage()),
         HttpStatus.BAD_REQUEST);
   }
 
-
   /**
    * Handles an AccessDenied Exception thrown by a REST API web service endpoint, HTTP request
    * handler method.
@@ -106,9 +117,8 @@ public class ManagementControllerAdvice {
   public ResponseEntity<ClusterManagementResult> handleException(
       final AccessDeniedException cause) {
     return new ResponseEntity<>(
-        new ClusterManagementResult(ClusterManagementResult.StatusCode.UNAUTHORIZED,
+        new ClusterManagementResult(StatusCode.UNAUTHORIZED,
             cause.getMessage()),
         HttpStatus.FORBIDDEN);
   }
-
 }
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java
index 3984944..8fd60cb 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/MemberManagementController.java
@@ -28,9 +28,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import org.apache.geode.management.api.ClusterManagementException;
 import org.apache.geode.management.api.ClusterManagementListResult;
+import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.api.ClusterManagementResult.StatusCode;
 import org.apache.geode.management.configuration.MemberConfig;
-import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
 import org.apache.geode.management.runtime.MemberInformation;
 
 @Controller("members")
@@ -45,8 +47,8 @@ public class MemberManagementController extends AbstractManagementController {
     ClusterManagementListResult<MemberConfig, MemberInformation> result =
         clusterManagementService.list(config);
     if (result.getRuntimeResult().size() == 0) {
-      throw new EntityNotFoundException(
-          "Member with id = " + config.getId() + " not found.");
+      throw new ClusterManagementException(new ClusterManagementResult(StatusCode.ENTITY_NOT_FOUND,
+          "Member with id = " + config.getId() + " not found."));
     }
 
     return new ResponseEntity<>(result,
diff --git a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
index 5085237..abe7e78 100644
--- a/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
+++ b/geode-web-management/src/main/java/org/apache/geode/management/internal/rest/controllers/RegionManagementController.java
@@ -39,10 +39,11 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import org.apache.geode.cache.configuration.RegionConfig;
+import org.apache.geode.management.api.ClusterManagementException;
 import org.apache.geode.management.api.ClusterManagementListResult;
 import org.apache.geode.management.api.ClusterManagementResult;
+import org.apache.geode.management.api.ClusterManagementResult.StatusCode;
 import org.apache.geode.management.api.ConfigurationResult;
-import org.apache.geode.management.internal.exceptions.EntityNotFoundException;
 import org.apache.geode.management.runtime.RuntimeInfo;
 import org.apache.geode.management.runtime.RuntimeRegionInfo;
 import org.apache.geode.security.ResourcePermission.Operation;
@@ -150,11 +151,13 @@ public class RegionManagementController extends AbstractManagementController {
     List<ConfigurationResult<RegionConfig.Index, RuntimeInfo>> indexList = result.getResult();
 
     if (indexList.size() == 0) {
-      throw new EntityNotFoundException("Index " + id + " not found.");
+      throw new ClusterManagementException(
+          new ClusterManagementResult(StatusCode.ENTITY_NOT_FOUND, "Index " + id + " not found."));
     }
 
     if (indexList.size() > 1) {
-      throw new IllegalStateException("More than one entity found.");
+      throw new ClusterManagementException(
+          new ClusterManagementResult(StatusCode.ERROR, "More than one entity found."));
     }
 
     result.setResult(indexList);


Mime
View raw message