From d547201c45dbd85042569ec1ebb1cf32e341a9f7 Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Thu, 7 Nov 2024 17:55:27 +0300 Subject: [PATCH 1/5] IGNITE-23632 Support force deactivation flag in thin client --- .../apache/ignite/client/ClientCluster.java | 14 +++++++++ .../client/thin/ClientClusterImpl.java | 14 +++++++++ .../client/thin/ProtocolBitmaskFeature.java | 6 +++- .../platform/client/ClientBitmaskFeature.java | 6 +++- .../platform/client/ClientMessageParser.java | 2 +- .../ClientClusterChangeStateRequest.java | 25 ++++++++++++++-- .../internal/client/thin/ClusterApiTest.java | 30 +++++++++++++++++++ 7 files changed, 91 insertions(+), 6 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java b/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java index fc34b41d87d5a..3741ccc5d893c 100644 --- a/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java +++ b/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java @@ -18,6 +18,7 @@ package org.apache.ignite.client; import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.lang.IgniteExperimental; /** * Thin client cluster facade. Represents whole cluster (all available nodes). @@ -41,6 +42,19 @@ public interface ClientCluster extends ClientClusterGroup { */ public void state(ClusterState newState) throws ClientException; + /** + * Changes current cluster state to given {@code newState} cluster state. + *

+ * NOTE: + * Deactivation clears in-memory caches (without persistence) including the system caches. + * + * @param newState New cluster state. + * @param forceDeactivation If {@code true}, cluster deactivation will be forced. + * @throws ClientException If change state operation failed. + */ + @IgniteExperimental + public void state(ClusterState newState, boolean forceDeactivation) throws ClientException; + /** * Disables write-ahead logging for specified cache. When WAL is disabled, changes are not logged to disk. * This significantly improves cache update speed. The drawback is absence of local crash-recovery guarantees. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java index 6dfc5bf483e65..ede0b63b57dce 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java @@ -54,6 +54,11 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster /** {@inheritDoc} */ @Override public void state(ClusterState newState) throws ClientException { + state(newState, true); + } + + /** {@inheritDoc} */ + @Override public void state(ClusterState newState, boolean forceDeactivation) throws ClientException { try { ch.service(ClientOperation.CLUSTER_CHANGE_STATE, req -> { @@ -67,6 +72,15 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster } req.out().writeByte((byte)newState.ordinal()); + + if (protocolCtx.isFeatureSupported(ProtocolBitmaskFeature.FORCE_DEACTIVATION_FLAG)) { + req.out().writeBoolean(forceDeactivation); + } + else if (forceDeactivation) { + throw new ClientFeatureNotSupportedByServerException( + "Force deactivation flag is not supported by the server" + ); + } }, null ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ProtocolBitmaskFeature.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ProtocolBitmaskFeature.java index 1a0fb9d714829..e3ff013fd8604 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ProtocolBitmaskFeature.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ProtocolBitmaskFeature.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.EnumSet; import org.apache.ignite.client.ClientServices; +import org.apache.ignite.cluster.ClusterState; /** * Defines supported bitmask features for thin client. @@ -83,7 +84,10 @@ public enum ProtocolBitmaskFeature { CACHE_INVOKE(17), /** Transaction aware queries. */ - TX_AWARE_QUERIES(18); + TX_AWARE_QUERIES(18), + + /** Force deactivation flag. See {@link org.apache.ignite.client.ClientCluster#state(ClusterState, boolean)}. */ + FORCE_DEACTIVATION_FLAG(19); /** */ private static final EnumSet ALL_FEATURES_AS_ENUM_SET = diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientBitmaskFeature.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientBitmaskFeature.java index d51b8eaaa743e..dc3187b955453 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientBitmaskFeature.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientBitmaskFeature.java @@ -19,6 +19,7 @@ import java.util.EnumSet; import org.apache.ignite.client.ClientServices; +import org.apache.ignite.cluster.ClusterState; import org.apache.ignite.internal.ThinProtocolFeature; import org.apache.ignite.internal.client.thin.TcpClientCache; @@ -81,7 +82,10 @@ public enum ClientBitmaskFeature implements ThinProtocolFeature { CACHE_INVOKE(17), /** Transaction aware queries. */ - TX_AWARE_QUERIES(18); + TX_AWARE_QUERIES(18), + + /** Force deactivation flag. See {@link org.apache.ignite.client.ClientCluster#state(ClusterState, boolean)}. */ + FORCE_DEACTIVATION_FLAG(19); /** */ private static final EnumSet ALL_FEATURES_AS_ENUM_SET = diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java index 60a897685d353..8684a6a1fed36 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java @@ -615,7 +615,7 @@ public ClientListenerRequest decode(BinaryReaderExImpl reader) { return new ClientClusterGetStateRequest(reader); case OP_CLUSTER_CHANGE_STATE: - return new ClientClusterChangeStateRequest(reader); + return new ClientClusterChangeStateRequest(reader, protocolCtx); case OP_CLUSTER_CHANGE_WAL_STATE: return new ClientClusterWalChangeStateRequest(reader); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java index e8b737962c4d7..126f056591b1d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java @@ -17,12 +17,17 @@ package org.apache.ignite.internal.processors.platform.client.cluster; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.binary.BinaryRawReader; import org.apache.ignite.cluster.ClusterState; import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; +import org.apache.ignite.internal.processors.platform.client.ClientProtocolContext; import org.apache.ignite.internal.processors.platform.client.ClientRequest; import org.apache.ignite.internal.processors.platform.client.ClientResponse; +import static org.apache.ignite.internal.processors.platform.client.ClientBitmaskFeature.FORCE_DEACTIVATION_FLAG; + /** * Cluster status request. */ @@ -30,21 +35,35 @@ public class ClientClusterChangeStateRequest extends ClientRequest { /** Next state. */ private final ClusterState state; + /** If {@code true}, cluster deactivation will be forced. */ + private final boolean forceDeactivation; + /** * Constructor. * * @param reader Reader. */ - public ClientClusterChangeStateRequest(BinaryRawReader reader) { + public ClientClusterChangeStateRequest(BinaryRawReader reader, ClientProtocolContext protocolCtx) { super(reader); state = ClusterState.fromOrdinal(reader.readByte()); + forceDeactivation = !protocolCtx.isFeatureSupported(FORCE_DEACTIVATION_FLAG) || reader.readBoolean(); } /** {@inheritDoc} */ @Override public ClientResponse process(ClientConnectionContext ctx) { - ctx.kernalContext().grid().cluster().state(state); + try { + ctx.kernalContext().state().changeGlobalState( + state, + forceDeactivation, + ctx.kernalContext().cluster().get().forServers().nodes(), + false + ).get(); - return new ClientResponse(requestId()); + return new ClientResponse(requestId()); + } + catch (IgniteCheckedException e) { + throw new IgniteException(e); + } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java index 5540ea3833a60..edf149fce7496 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java @@ -18,6 +18,8 @@ package org.apache.ignite.internal.client.thin; import org.apache.ignite.IgniteCluster; +import org.apache.ignite.IgniteException; +import org.apache.ignite.client.ClientCacheConfiguration; import org.apache.ignite.client.ClientCluster; import org.apache.ignite.client.IgniteClient; import org.apache.ignite.cluster.ClusterState; @@ -26,6 +28,8 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.junit.Test; +import static org.apache.ignite.testframework.GridTestUtils.assertThrows; + /** * Checks cluster state/WAL state operations for thin client. */ @@ -36,6 +40,9 @@ public class ClusterApiTest extends AbstractThinClientTest { .setDataStorageConfiguration(new DataStorageConfiguration() .setDefaultDataRegionConfiguration(new DataRegionConfiguration() .setPersistenceEnabled(true))) + .setDataStorageConfiguration(new DataStorageConfiguration() + .setDataRegionConfigurations(new DataRegionConfiguration() + .setName("non-persistent"))) .setClusterStateOnStart(ClusterState.INACTIVE); } @@ -73,6 +80,29 @@ public void testClusterState() throws Exception { } } + /** + * Test change cluster state operation by thin client. + */ + @Test + public void testForceDeactivation() { + try (IgniteClient client = startClient(0)) { + client.cluster().state(ClusterState.ACTIVE); + + client.getOrCreateCache(new ClientCacheConfiguration() + .setName(DEFAULT_CACHE_NAME) + .setDataRegionName("non-persistent")); + + assertThrows(log, () -> client.cluster().state(ClusterState.INACTIVE, false), IgniteException.class, + "Deactivation stopped. Deactivation clears in-memory caches (without persistence) including the system caches."); + + assertTrue(grid(0).cluster().state().active()); + + client.cluster().state(ClusterState.INACTIVE, true); + + assertFalse(grid(0).cluster().state().active()); + } + } + /** * Test change WAL state for cache operation by thin client. */ From 2408d8069ff25ca36a462591dd2791b2a9cb79f2 Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Tue, 19 Nov 2024 13:14:29 +0300 Subject: [PATCH 2/5] Review fixes --- .../apache/ignite/client/ClientCluster.java | 14 ------------- .../client/thin/ClientClusterImpl.java | 20 +++++++++++++------ .../internal/client/thin/ClusterApiTest.java | 7 ++++--- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java b/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java index 3741ccc5d893c..fc34b41d87d5a 100644 --- a/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java +++ b/modules/core/src/main/java/org/apache/ignite/client/ClientCluster.java @@ -18,7 +18,6 @@ package org.apache.ignite.client; import org.apache.ignite.cluster.ClusterState; -import org.apache.ignite.lang.IgniteExperimental; /** * Thin client cluster facade. Represents whole cluster (all available nodes). @@ -42,19 +41,6 @@ public interface ClientCluster extends ClientClusterGroup { */ public void state(ClusterState newState) throws ClientException; - /** - * Changes current cluster state to given {@code newState} cluster state. - *

- * NOTE: - * Deactivation clears in-memory caches (without persistence) including the system caches. - * - * @param newState New cluster state. - * @param forceDeactivation If {@code true}, cluster deactivation will be forced. - * @throws ClientException If change state operation failed. - */ - @IgniteExperimental - public void state(ClusterState newState, boolean forceDeactivation) throws ClientException; - /** * Disables write-ahead logging for specified cache. When WAL is disabled, changes are not logged to disk. * This significantly improves cache update speed. The drawback is absence of local crash-recovery guarantees. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java index ede0b63b57dce..e2fba8e0113b7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java @@ -26,7 +26,7 @@ /** * Implementation of {@link ClientCluster}. */ -class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster { +public class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster { /** Default cluster group. */ private final ClientClusterGroupImpl dfltClusterGrp; @@ -57,8 +57,17 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster state(newState, true); } - /** {@inheritDoc} */ - @Override public void state(ClusterState newState, boolean forceDeactivation) throws ClientException { + /** + * Changes current cluster state to given {@code newState} cluster state. + *

+ * NOTE: + * Deactivation clears in-memory caches (without persistence) including the system caches. + * + * @param newState New cluster state. + * @param forceDeactivation If {@code true}, cluster deactivation will be forced. + * @throws ClientException If change state operation failed. + */ + public void state(ClusterState newState, boolean forceDeactivation) throws ClientException { try { ch.service(ClientOperation.CLUSTER_CHANGE_STATE, req -> { @@ -73,10 +82,9 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster req.out().writeByte((byte)newState.ordinal()); - if (protocolCtx.isFeatureSupported(ProtocolBitmaskFeature.FORCE_DEACTIVATION_FLAG)) { + if (protocolCtx.isFeatureSupported(ProtocolBitmaskFeature.FORCE_DEACTIVATION_FLAG)) req.out().writeBoolean(forceDeactivation); - } - else if (forceDeactivation) { + else if (!forceDeactivation) { throw new ClientFeatureNotSupportedByServerException( "Force deactivation flag is not supported by the server" ); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java index edf149fce7496..56e9e39a444be 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java @@ -92,12 +92,13 @@ public void testForceDeactivation() { .setName(DEFAULT_CACHE_NAME) .setDataRegionName("non-persistent")); - assertThrows(log, () -> client.cluster().state(ClusterState.INACTIVE, false), IgniteException.class, - "Deactivation stopped. Deactivation clears in-memory caches (without persistence) including the system caches."); + assertThrows(log, () -> ((ClientClusterImpl)client.cluster()).state(ClusterState.INACTIVE, false), + IgniteException.class, "Deactivation stopped. " + + "Deactivation clears in-memory caches (without persistence) including the system caches."); assertTrue(grid(0).cluster().state().active()); - client.cluster().state(ClusterState.INACTIVE, true); + ((ClientClusterImpl)client.cluster()).state(ClusterState.INACTIVE, true); assertFalse(grid(0).cluster().state().active()); } From 332742ee1c29c1fd79eb8728ee7ec8f25065b1b8 Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Wed, 20 Nov 2024 23:58:23 +0300 Subject: [PATCH 3/5] Fixed test --- .../apache/ignite/internal/client/thin/ClusterApiTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java index 56e9e39a444be..5d031dca3d9f9 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterApiTest.java @@ -39,8 +39,7 @@ public class ClusterApiTest extends AbstractThinClientTest { return super.getConfiguration(igniteInstanceName) .setDataStorageConfiguration(new DataStorageConfiguration() .setDefaultDataRegionConfiguration(new DataRegionConfiguration() - .setPersistenceEnabled(true))) - .setDataStorageConfiguration(new DataStorageConfiguration() + .setPersistenceEnabled(true)) .setDataRegionConfigurations(new DataRegionConfiguration() .setName("non-persistent"))) .setClusterStateOnStart(ClusterState.INACTIVE); @@ -89,7 +88,7 @@ public void testForceDeactivation() { client.cluster().state(ClusterState.ACTIVE); client.getOrCreateCache(new ClientCacheConfiguration() - .setName(DEFAULT_CACHE_NAME) + .setName("non-persistent-cache") .setDataRegionName("non-persistent")); assertThrows(log, () -> ((ClientClusterImpl)client.cluster()).state(ClusterState.INACTIVE, false), From 804d898d105243db14308d0c1c75cb44bd37dcf0 Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Thu, 5 Dec 2024 23:25:32 +0300 Subject: [PATCH 4/5] Fixed test --- .../security/cluster/ClusterStatePermissionTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java index a5a9c2eef7ea1..ffc349fc37f23 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java @@ -23,8 +23,8 @@ import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCluster; import org.apache.ignite.IgniteException; -import org.apache.ignite.client.ClientAuthorizationException; import org.apache.ignite.client.ClientCluster; +import org.apache.ignite.client.ClientException; import org.apache.ignite.client.Config; import org.apache.ignite.client.IgniteClient; import org.apache.ignite.cluster.ClusterState; @@ -224,15 +224,15 @@ private void doTestChangeState(ClusterState[] states, boolean allowed) throws Ex * Ensures that a proper error occurs on cluster change state action. */ private void ensureThrows(Consumer action, ClusterState stateTo) { - Class cause = SecurityException.class; String errMsg = "Authorization failed [perm=" + ADMIN_CLUSTER_STATE; + Class cause; - if (Initiator.THIN_CLIENT == initiator) { - cause = ClientAuthorizationException.class; - errMsg = "User is not authorized to perform this operation"; - } + if (Initiator.THIN_CLIENT == initiator) + cause = ClientException.class; else if (Initiator.REMOTE_CONTROL == initiator) cause = GridClientException.class; + else + cause = SecurityException.class; assertThrowsAnyCause( null, From 5a11868c3d755f616ea1f736a87a2b9816c4618b Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Thu, 5 Dec 2024 23:55:43 +0300 Subject: [PATCH 5/5] Fixed test --- .../cluster/ClientClusterChangeStateRequest.java | 4 ++-- .../security/cluster/ClusterStatePermissionTest.java | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java index 126f056591b1d..48f73f9279290 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cluster/ClientClusterChangeStateRequest.java @@ -18,13 +18,13 @@ package org.apache.ignite.internal.processors.platform.client.cluster; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteException; import org.apache.ignite.binary.BinaryRawReader; import org.apache.ignite.cluster.ClusterState; import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; import org.apache.ignite.internal.processors.platform.client.ClientProtocolContext; import org.apache.ignite.internal.processors.platform.client.ClientRequest; import org.apache.ignite.internal.processors.platform.client.ClientResponse; +import org.apache.ignite.internal.util.typedef.internal.U; import static org.apache.ignite.internal.processors.platform.client.ClientBitmaskFeature.FORCE_DEACTIVATION_FLAG; @@ -63,7 +63,7 @@ public ClientClusterChangeStateRequest(BinaryRawReader reader, ClientProtocolCon return new ClientResponse(requestId()); } catch (IgniteCheckedException e) { - throw new IgniteException(e); + throw U.convertException(e); } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java index ffc349fc37f23..a5a9c2eef7ea1 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/cluster/ClusterStatePermissionTest.java @@ -23,8 +23,8 @@ import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCluster; import org.apache.ignite.IgniteException; +import org.apache.ignite.client.ClientAuthorizationException; import org.apache.ignite.client.ClientCluster; -import org.apache.ignite.client.ClientException; import org.apache.ignite.client.Config; import org.apache.ignite.client.IgniteClient; import org.apache.ignite.cluster.ClusterState; @@ -224,15 +224,15 @@ private void doTestChangeState(ClusterState[] states, boolean allowed) throws Ex * Ensures that a proper error occurs on cluster change state action. */ private void ensureThrows(Consumer action, ClusterState stateTo) { + Class cause = SecurityException.class; String errMsg = "Authorization failed [perm=" + ADMIN_CLUSTER_STATE; - Class cause; - if (Initiator.THIN_CLIENT == initiator) - cause = ClientException.class; + if (Initiator.THIN_CLIENT == initiator) { + cause = ClientAuthorizationException.class; + errMsg = "User is not authorized to perform this operation"; + } else if (Initiator.REMOTE_CONTROL == initiator) cause = GridClientException.class; - else - cause = SecurityException.class; assertThrowsAnyCause( null,