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

shishkovilja pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 5a9692d3eaf IGNITE-28944 Refactor SecurityPermissionSet (#13424)
5a9692d3eaf is described below

commit 5a9692d3eaf204f4d9f39aaf792a881d36315a09
Author: Ilya Shishkov <[email protected]>
AuthorDate: Thu Aug 6 17:55:08 2026 +0300

    IGNITE-28944 Refactor SecurityPermissionSet (#13424)
---
 .../processors/security/SecurityUtils.java         |  46 ++++++++-
 .../security/SecurityBasicPermissionSet.java       |  72 +++++++++-----
 .../plugin/security/SecurityPermissionSet.java     |  10 +-
 .../security/SecurityPermissionSetBuilder.java     |  24 ++---
 .../security/impl/TestSecurityProcessor.java       |  11 ++-
 ...ecurityBasicPermissionSetSerializationTest.java | 103 ++++++++++-----------
 .../security/SecurityPermissionSetBuilderTest.java |  36 +++----
 .../junits/spi/GridSpiAbstractTest.java            |  10 +-
 .../cpp/core-test/config/compute-security.xml      |  28 ++++--
 .../Config/Compute/compute-security.xml            |  40 +++++---
 10 files changed, 216 insertions(+), 164 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityUtils.java
index b0529868019..452a13cdd54 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityUtils.java
@@ -29,13 +29,14 @@ import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.Callable;
+import java.util.stream.Collectors;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteSystemProperties;
@@ -132,14 +133,49 @@ public class SecurityUtils {
      * @return Allow all service permissions.
      */
     public static Map<String, Collection<SecurityPermission>> 
compatibleServicePermissions() {
-        Map<String, Collection<SecurityPermission>> srvcPerms = new 
HashMap<>();
+        Map<String, EnumSet<SecurityPermission>> srvcPerms = new HashMap<>();
 
-        srvcPerms.put("*", Arrays.asList(
+        srvcPerms.put("*", EnumSet.of(
             SecurityPermission.SERVICE_CANCEL,
             SecurityPermission.SERVICE_DEPLOY,
             SecurityPermission.SERVICE_INVOKE));
 
-        return srvcPerms;
+        return upcast(srvcPerms);
+    }
+
+    /** */
+    @SuppressWarnings("rawtypes")
+    public static Map<String, Collection<SecurityPermission>> 
upcast(Map<String, EnumSet<SecurityPermission>> map) {
+        return (Map<String, Collection<SecurityPermission>>)(Map)map;
+    }
+
+    /** */
+    @SuppressWarnings("rawtypes")
+    public static Map<String, EnumSet<SecurityPermission>> 
downcast(Map<String, Collection<SecurityPermission>> map) {
+        return (Map<String, EnumSet<SecurityPermission>>)(Map)map;
+    }
+
+    /**
+     * @param permissionsMap Permissions map.
+     * @return Map with enum sets of security permissions.
+     */
+    public static Map<String, Collection<SecurityPermission>> 
normalizeValueType(
+        Map<String, Collection<SecurityPermission>> permissionsMap
+    ) {
+        return permissionsMap.entrySet().stream()
+            .collect(Collectors.toMap(Map.Entry::getKey, e -> 
copySafe(e.getValue())));
+    }
+
+    /** */
+    public static EnumSet<SecurityPermission> 
copySafe(Collection<SecurityPermission> col) {
+        if (col instanceof EnumSet<SecurityPermission> enumSet)
+            return enumSet;
+
+        // Enum set does not allow to copy empty collections, so we check it 
explicitly.
+        if (F.isEmpty(col))
+            return EnumSet.noneOf(SecurityPermission.class);
+
+        return EnumSet.copyOf(col);
     }
 
     /**
@@ -366,7 +402,7 @@ public class SecurityUtils {
     }
 
     /** */
-    private static void authorizeAll(IgniteSecurity security, Map<String, 
Collection<SecurityPermission>> permissions) {
+    private static void authorizeAll(IgniteSecurity security, Map<String, 
EnumSet<SecurityPermission>> permissions) {
         if (F.isEmpty(permissions))
             return;
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
index 3daf23d9088..5256acb83ab 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
@@ -22,10 +22,12 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import org.apache.ignite.internal.Order;
+import org.apache.ignite.internal.SelfMarshallingMessage;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -33,14 +35,18 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
 
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.compatibleServicePermissions;
+import static 
org.apache.ignite.internal.processors.security.SecurityUtils.copySafe;
+import static 
org.apache.ignite.internal.processors.security.SecurityUtils.downcast;
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.isSecurityCompatibilityMode;
+import static 
org.apache.ignite.internal.processors.security.SecurityUtils.normalizeValueType;
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.serializeVersion;
+import static 
org.apache.ignite.internal.processors.security.SecurityUtils.upcast;
 
 /**
  * Simple implementation of {@link SecurityPermissionSet} interface.
  * Provides convenient way to specify permission set in the XML configuration.
  */
-public class SecurityBasicPermissionSet implements SecurityPermissionSet {
+public class SecurityBasicPermissionSet implements SecurityPermissionSet, 
SelfMarshallingMessage {
     /** Serial version uid. */
     private static final long serialVersionUID = 0L;
 
@@ -64,7 +70,7 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
     /** System permissions. */
     @GridToStringInclude
     @Order(3)
-    Collection<SecurityPermission> sysPermissions;
+    @Nullable Collection<SecurityPermission> sysPermissions;
 
     /** Default allow all. */
     @Order(4)
@@ -75,10 +81,10 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
      *
      * @param cachePermissions Cache permissions.
      */
-    public void setCachePermissions(Map<String, 
Collection<SecurityPermission>> cachePermissions) {
+    public void setCachePermissions(Map<String, EnumSet<SecurityPermission>> 
cachePermissions) {
         A.notNull(cachePermissions, "cachePermissions");
 
-        this.cachePermissions = cachePermissions;
+        this.cachePermissions = normalizeValueType(upcast(cachePermissions));
     }
 
     /**
@@ -86,10 +92,10 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
      *
      * @param taskPermissions Task permissions.
      */
-    public void setTaskPermissions(Map<String, Collection<SecurityPermission>> 
taskPermissions) {
+    public void setTaskPermissions(Map<String, EnumSet<SecurityPermission>> 
taskPermissions) {
         A.notNull(taskPermissions, "taskPermissions");
 
-        this.taskPermissions = taskPermissions;
+        this.taskPermissions = normalizeValueType(upcast(taskPermissions));
     }
 
     /**
@@ -97,10 +103,10 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
      *
      * @param srvcPermissions Service permissions.
      */
-    public void setServicePermissions(Map<String, 
Collection<SecurityPermission>> srvcPermissions) {
-        A.notNull(taskPermissions, "servicePermissions");
+    public void setServicePermissions(Map<String, EnumSet<SecurityPermission>> 
srvcPermissions) {
+        A.notNull(srvcPermissions, "servicePermissions");
 
-        this.srvcPermissions = srvcPermissions;
+        this.srvcPermissions = normalizeValueType(upcast(srvcPermissions));
     }
 
     /**
@@ -108,7 +114,7 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
      *
      * @param sysPermissions System permissions.
      */
-    public void setSystemPermissions(Collection<SecurityPermission> 
sysPermissions) {
+    public void setSystemPermissions(@Nullable EnumSet<SecurityPermission> 
sysPermissions) {
         this.sysPermissions = sysPermissions;
     }
 
@@ -122,23 +128,23 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
     }
 
     /** {@inheritDoc} */
-    @Override public Map<String, Collection<SecurityPermission>> 
cachePermissions() {
-        return cachePermissions;
+    @Override public Map<String, EnumSet<SecurityPermission>> 
cachePermissions() {
+        return downcast(cachePermissions);
     }
 
     /** {@inheritDoc} */
-    @Override public Map<String, Collection<SecurityPermission>> 
taskPermissions() {
-        return taskPermissions;
+    @Override public Map<String, EnumSet<SecurityPermission>> 
taskPermissions() {
+        return downcast(taskPermissions);
     }
 
     /** {@inheritDoc} */
-    @Override public Map<String, Collection<SecurityPermission>> 
servicePermissions() {
-        return srvcPermissions;
+    @Override public Map<String, EnumSet<SecurityPermission>> 
servicePermissions() {
+        return downcast(srvcPermissions);
     }
 
     /** {@inheritDoc} */
-    @Nullable @Override public Collection<SecurityPermission> 
systemPermissions() {
-        return sysPermissions;
+    @Nullable @Override public EnumSet<SecurityPermission> systemPermissions() 
{
+        return (EnumSet<SecurityPermission>)sysPermissions;
     }
 
     /** {@inheritDoc} */
@@ -175,9 +181,7 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
         return res;
     }
 
-    /**
-     * @param out Out.
-     */
+    /** */
     private void writeObject(ObjectOutputStream out) throws IOException {
         out.defaultWriteObject();
 
@@ -185,9 +189,7 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
             U.writeMap(out, srvcPermissions);
     }
 
-    /**
-     * @param in In.
-     */
+    /** */
     private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
         in.defaultReadObject();
 
@@ -201,10 +203,32 @@ public class SecurityBasicPermissionSet implements 
SecurityPermissionSet {
             else
                 srvcPermissions = Collections.emptyMap();
         }
+
+        normalize();
     }
 
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(SecurityBasicPermissionSet.class, this);
     }
+
+    /** {@inheritDoc} */
+    @Override public void selfMarshal() {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void selfUnmarshal() {
+        // Message framework uses ArrayList for ordinary collections,
+        // so we need to convert it to appropriate form explicitly.
+        normalize();
+    }
+
+    /** */
+    private void normalize() {
+        cachePermissions = normalizeValueType(cachePermissions);
+        taskPermissions = normalizeValueType(taskPermissions);
+        srvcPermissions = normalizeValueType(srvcPermissions);
+        sysPermissions = sysPermissions == null ? null : 
copySafe(sysPermissions);
+    }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
index 20e78c6efab..47bb11517f7 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
@@ -18,7 +18,7 @@
 package org.apache.ignite.plugin.security;
 
 import java.io.Serializable;
-import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Map;
 import org.apache.ignite.plugin.extensions.communication.Message;
 import org.jetbrains.annotations.Nullable;
@@ -48,7 +48,7 @@ public interface SecurityPermissionSet extends Serializable, 
Message {
      *
      * @return Map of task names to task permissions.
      */
-    public Map<String, Collection<SecurityPermission>> taskPermissions();
+    public Map<String, EnumSet<SecurityPermission>> taskPermissions();
 
     /**
      * Map of cache names to cache permissions. Wildcards are allowed at the
@@ -56,7 +56,7 @@ public interface SecurityPermissionSet extends Serializable, 
Message {
      *
      * @return Map of cache names to cache permissions.
      */
-    public Map<String, Collection<SecurityPermission>> cachePermissions();
+    public Map<String, EnumSet<SecurityPermission>> cachePermissions();
 
     /**
      * Map of service names to service permissions. Wildcards are allowed at 
the
@@ -64,12 +64,12 @@ public interface SecurityPermissionSet extends 
Serializable, Message {
      *
      * @return Map of service names to service permissions.
      */
-    public Map<String, Collection<SecurityPermission>> servicePermissions();
+    public Map<String, EnumSet<SecurityPermission>> servicePermissions();
 
     /**
      * Collection of system-wide permissions (events enable/disable, Visor 
task execution).
      *
      * @return Collection of system-wide permissions.
      */
-    @Nullable public Collection<SecurityPermission> systemPermissions();
+    @Nullable public EnumSet<SecurityPermission> systemPermissions();
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilder.java
 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilder.java
index 49fcf236bce..18b21d0ab01 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilder.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilder.java
@@ -19,15 +19,13 @@ package org.apache.ignite.plugin.security;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
 import static java.util.Collections.unmodifiableMap;
-import static java.util.Collections.unmodifiableSet;
 
 /**
  * Provides a convenient way to create a permission set.
@@ -53,16 +51,16 @@ import static java.util.Collections.unmodifiableSet;
  */
 public class SecurityPermissionSetBuilder {
     /** Cache permissions.*/
-    private Map<String, Collection<SecurityPermission>> cachePerms = new 
HashMap<>();
+    private Map<String, EnumSet<SecurityPermission>> cachePerms = new 
HashMap<>();
 
     /** Task permissions.*/
-    private Map<String, Collection<SecurityPermission>> taskPerms = new 
HashMap<>();
+    private Map<String, EnumSet<SecurityPermission>> taskPerms = new 
HashMap<>();
 
     /** Service permissions.*/
-    private Map<String, Collection<SecurityPermission>> srvcPerms = new 
HashMap<>();
+    private Map<String, EnumSet<SecurityPermission>> srvcPerms = new 
HashMap<>();
 
     /** System permissions.*/
-    private Set<SecurityPermission> sysPerms = new HashSet<>();
+    private EnumSet<SecurityPermission> sysPerms = 
EnumSet.noneOf(SecurityPermission.class);
 
     /** Default allow all.*/
     private boolean dfltAllowAll;
@@ -214,7 +212,7 @@ public class SecurityPermissionSetBuilder {
      * @param perms Permission.
      */
     private void append(
-        Map<String, Collection<SecurityPermission>> permsMap,
+        Map<String, EnumSet<SecurityPermission>> permsMap,
         String name,
         Collection<SecurityPermission> perms
     ) {
@@ -222,12 +220,8 @@ public class SecurityPermissionSetBuilder {
         assert name != null;
         assert perms != null;
 
-        Collection<SecurityPermission> col = permsMap.get(name);
-
-        if (col == null)
-            permsMap.put(name, perms);
-        else
-            col.addAll(perms);
+        permsMap.computeIfAbsent(name, n -> 
EnumSet.noneOf(SecurityPermission.class))
+            .addAll(perms);
     }
 
     /**
@@ -242,7 +236,7 @@ public class SecurityPermissionSetBuilder {
         permSet.setCachePermissions(unmodifiableMap(cachePerms));
         permSet.setTaskPermissions(unmodifiableMap(taskPerms));
         permSet.setServicePermissions(unmodifiableMap(srvcPerms));
-        permSet.setSystemPermissions(unmodifiableSet(sysPerms));
+        permSet.setSystemPermissions(EnumSet.copyOf(sysPerms));
 
         return permSet;
     }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/impl/TestSecurityProcessor.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/impl/TestSecurityProcessor.java
index 06500e3ffbf..e9f27d87480 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/impl/TestSecurityProcessor.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/impl/TestSecurityProcessor.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
@@ -261,17 +262,17 @@ public class TestSecurityProcessor extends 
GridProcessorAdapter implements GridS
 
     /** */
     private static boolean contains(
-        Map<String, Collection<SecurityPermission>> userPerms,
+        Map<String, EnumSet<SecurityPermission>> userPerms,
         boolean dfltAllowAll,
         String name,
         SecurityPermission perm
     ) {
-        Collection<SecurityPermission> perms = userPerms.get(name);
+        EnumSet<SecurityPermission> perms = userPerms.get(name);
 
         if (perms == null)
             return dfltAllowAll;
 
-        return perms.stream().anyMatch(perm::equals);
+        return perms.contains(perm);
     }
 
     /** */
@@ -279,11 +280,11 @@ public class TestSecurityProcessor extends 
GridProcessorAdapter implements GridS
         SecurityPermissionSet userPerms,
         SecurityPermission perm
     ) {
-        Collection<SecurityPermission> sysPerms = 
userPerms.systemPermissions();
+        EnumSet<SecurityPermission> sysPerms = userPerms.systemPermissions();
 
         if (F.isEmpty(sysPerms))
             return userPerms.defaultAllowAll();
 
-        return sysPerms.stream().anyMatch(perm::equals);
+        return sysPerms.contains(perm);
     }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSetSerializationTest.java
 
b/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSetSerializationTest.java
index 5d94d4e8847..83d18941fe4 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSetSerializationTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSetSerializationTest.java
@@ -18,23 +18,23 @@
 package org.apache.ignite.plugin.security;
 
 import java.nio.ByteBuffer;
-import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.CoreMessagesProvider;
 import org.apache.ignite.internal.direct.DirectMessageReader;
 import org.apache.ignite.internal.direct.DirectMessageWriter;
 import 
org.apache.ignite.internal.managers.communication.IgniteMessageFactoryImpl;
+import org.apache.ignite.internal.managers.communication.MessageMarshalling;
 import org.apache.ignite.internal.util.nio.MessageSerialization;
-import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.plugin.extensions.communication.MessageFactory;
 import 
org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.jetbrains.annotations.Nullable;
 import org.junit.Test;
 
 import static org.apache.ignite.internal.util.CommonUtils.makeMessageType;
@@ -60,15 +60,48 @@ public class SecurityBasicPermissionSetSerializationTest 
extends GridCommonAbstr
         SecurityBasicPermissionSet src = new SecurityBasicPermissionSet();
 
         src.setDefaultAllowAll(true);
-        src.setSystemPermissions(F.asList(ADMIN_CACHE, ADMIN_QUERY, null));
-        src.setTaskPermissions(Map.of("task", F.asList(TASK_EXECUTE, null, 
TASK_CANCEL)));
-        src.setServicePermissions(Map.of("service", Set.of(SERVICE_INVOKE, 
SERVICE_CANCEL)));
-        src.setCachePermissions(Map.of("cache", Set.of(CACHE_CREATE, 
CACHE_PUT)));
+        src.setSystemPermissions(EnumSet.of(ADMIN_CACHE, ADMIN_QUERY));
+        src.setTaskPermissions(Map.of("task", EnumSet.of(TASK_EXECUTE, 
TASK_CANCEL)));
+        src.setServicePermissions(Map.of("service", EnumSet.of(SERVICE_INVOKE, 
SERVICE_CANCEL)));
+        src.setCachePermissions(Map.of("cache", EnumSet.of(CACHE_CREATE, 
CACHE_PUT)));
 
-        src.setCachePermissions(Map.of("cache", Set.of(CACHE_CREATE, 
CACHE_PUT)));
         SecurityBasicPermissionSet res = writeAndReadBack(src);
 
-        assertTrue("Permission sets are not equal [src=" + src + ", res=" + 
res + "]", deepEquals(src, res));
+        assertEquals("Permission sets are not equal", src, res);
+        assertEquals("Hashes of permission sets are not equal [src=" + src + 
", res=" + res + "]",
+            src.hashCode(), res.hashCode());
+    }
+
+    /** */
+    @Test
+    public void testWithNullAndEmptyPermissions() throws Exception {
+        SecurityBasicPermissionSet src = new SecurityBasicPermissionSet();
+        src.setDefaultAllowAll(true);
+
+        EnumSet<SecurityPermission> emptyPerms = 
EnumSet.noneOf(SecurityPermission.class);
+
+        src.setSystemPermissions(emptyPerms);
+
+        HashMap<String, EnumSet<SecurityPermission>> taskPerms = new 
HashMap<>();
+        taskPerms.put("task1", null);
+        taskPerms.put("task2", emptyPerms);
+
+        src.setTaskPermissions(taskPerms);
+
+        SecurityBasicPermissionSet res = writeAndReadBack(src);
+
+        assertEquals("Permission sets are not equal", src, res);
+        assertEquals("Hashes of permission sets are not equal [src=" + src + 
", res=" + res + "]",
+            src.hashCode(), res.hashCode());
+
+        // Explicitly test 'null' for system permissions.
+        src.setSystemPermissions(null);
+
+        res = writeAndReadBack(src);
+
+        assertEquals("Permission sets are not equal", src, res);
+        assertEquals("Hashes of permission sets are not equal [src=" + src + 
", res=" + res + "]",
+            src.hashCode(), res.hashCode());
     }
 
     /**
@@ -82,6 +115,8 @@ public class SecurityBasicPermissionSetSerializationTest 
extends GridCommonAbstr
 
         GridTestUtils.setFieldValue(kctx.grid(), "msgFactory", msgFactory);
 
+        MessageMarshalling.marshal(msg, kctx, null);
+
         ByteBuffer buf = ByteBuffer.allocate(64 * 1024);
 
         DirectMessageWriter writer = new DirectMessageWriter(msgFactory);
@@ -98,52 +133,8 @@ public class SecurityBasicPermissionSetSerializationTest 
extends GridCommonAbstr
 
         assertTrue(MessageSerialization.readFrom(msgFactory, res, reader));
 
-        return res;
-    }
-
-    /**
-     * Perfroms deep equals of permission sets.
-     *
-     * @param lhs First permissions set for equality check.
-     * @param rhs Second permissions set for equality check.
-     * @return Whether specified permission sets are equal.
-     */
-    public static boolean deepEquals(SecurityPermissionSet lhs, 
SecurityPermissionSet rhs) {
-        if (lhs == rhs)
-            return true;
-
-        return lhs != null
-            && rhs != null
-            && lhs.defaultAllowAll() == rhs.defaultAllowAll()
-            && (F.isEmpty(rhs.systemPermissions()) && 
F.isEmpty(rhs.systemPermissions())
-            || F.eqNotOrdered(rhs.systemPermissions(), 
lhs.systemPermissions()))
-            && eqNotOrdered(rhs.taskPermissions(), lhs.taskPermissions())
-            && eqNotOrdered(rhs.servicePermissions(), lhs.servicePermissions())
-            && eqNotOrdered(rhs.cachePermissions(), lhs.cachePermissions());
-    }
+        MessageMarshalling.unmarshal(res, kctx, null, U.gridClassLoader());
 
-    /**
-     * @param m1 First map to check.
-     * @param m2 Second map to check
-     * @return {@code True} is maps are equal, {@code False} otherwise.
-     */
-    public static boolean eqNotOrdered(
-        @Nullable Map<String, Collection<SecurityPermission>> m1,
-        @Nullable Map<String, Collection<SecurityPermission>> m2) {
-        if (m1 == m2)
-            return true;
-
-        if (m1 == null || m2 == null)
-            return false;
-
-        if (m1.size() != m2.size())
-            return false;
-
-        for (Map.Entry<String, Collection<SecurityPermission>> e : 
m1.entrySet()) {
-            if (!F.eqNotOrdered(e.getValue(), m2.get(e.getKey())))
-                return false;
-        }
-
-        return true;
+        return res;
     }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilderTest.java
 
b/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilderTest.java
index 04fee907d95..11b35194231 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilderTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/plugin/security/SecurityPermissionSetBuilderTest.java
@@ -17,13 +17,11 @@
 
 package org.apache.ignite.plugin.security;
 
-import java.util.Collection;
-import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import org.apache.ignite.IgniteException;
-import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
@@ -52,25 +50,25 @@ public class SecurityPermissionSetBuilderTest extends 
GridCommonAbstractTest {
     public void testPermissionBuilder() {
         SecurityBasicPermissionSet exp = new SecurityBasicPermissionSet();
 
-        Map<String, Collection<SecurityPermission>> permCache = new 
HashMap<>();
-        permCache.put("cache1", permissions(CACHE_PUT, CACHE_REMOVE, 
CACHE_CREATE));
-        permCache.put("cache2", permissions(CACHE_READ, CACHE_DESTROY));
+        Map<String, EnumSet<SecurityPermission>> permCache = new HashMap<>();
+        permCache.put("cache1", EnumSet.of(CACHE_PUT, CACHE_REMOVE, 
CACHE_CREATE));
+        permCache.put("cache2", EnumSet.of(CACHE_READ, CACHE_DESTROY));
 
         exp.setCachePermissions(permCache);
 
-        Map<String, Collection<SecurityPermission>> permTask = new HashMap<>();
-        permTask.put("task1", permissions(TASK_CANCEL));
-        permTask.put("task2", permissions(TASK_EXECUTE));
+        Map<String, EnumSet<SecurityPermission>> permTask = new HashMap<>();
+        permTask.put("task1", EnumSet.of(TASK_CANCEL));
+        permTask.put("task2", EnumSet.of(TASK_EXECUTE));
 
         exp.setTaskPermissions(permTask);
 
-        Map<String, Collection<SecurityPermission>> permSrvc = new HashMap<>();
-        permSrvc.put("service1", permissions(SERVICE_DEPLOY));
-        permSrvc.put("service2", permissions(SERVICE_INVOKE));
+        Map<String, EnumSet<SecurityPermission>> permSrvc = new HashMap<>();
+        permSrvc.put("service1", EnumSet.of(SERVICE_DEPLOY));
+        permSrvc.put("service2", EnumSet.of(SERVICE_INVOKE));
 
         exp.setServicePermissions(permSrvc);
 
-        exp.setSystemPermissions(permissions(ADMIN_VIEW, EVENTS_ENABLE, 
JOIN_AS_SERVER, CACHE_CREATE, CACHE_DESTROY));
+        exp.setSystemPermissions(EnumSet.of(ADMIN_VIEW, EVENTS_ENABLE, 
JOIN_AS_SERVER, CACHE_CREATE, CACHE_DESTROY));
 
         final SecurityPermissionSetBuilder permsBuilder = new 
SecurityPermissionSetBuilder();
 
@@ -138,16 +136,4 @@ public class SecurityPermissionSetBuilderTest extends 
GridCommonAbstractTest {
         assertEquals(exp.systemPermissions(), actual.systemPermissions());
         assertEquals(exp.defaultAllowAll(), actual.defaultAllowAll());
     }
-
-    /**
-     * @param perms Permissions.
-     * @return Collection.
-     */
-    static Collection<SecurityPermission> permissions(SecurityPermission... 
perms) {
-        Collection<SecurityPermission> col = U.newHashSet(perms.length);
-
-        Collections.addAll(col, perms);
-
-        return col;
-    }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/spi/GridSpiAbstractTest.java
 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/spi/GridSpiAbstractTest.java
index 4c172b398a5..0a86bb6b579 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/spi/GridSpiAbstractTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/spi/GridSpiAbstractTest.java
@@ -20,8 +20,8 @@ package org.apache.ignite.testframework.junits.spi;
 import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -727,22 +727,22 @@ public abstract class GridSpiAbstractTest<T extends 
IgniteSpi> extends GridAbstr
         }
 
         /** {@inheritDoc} */
-        @Override public Map<String, Collection<SecurityPermission>> 
taskPermissions() {
+        @Override public Map<String, EnumSet<SecurityPermission>> 
taskPermissions() {
             return Collections.emptyMap();
         }
 
         /** {@inheritDoc} */
-        @Override public Map<String, Collection<SecurityPermission>> 
cachePermissions() {
+        @Override public Map<String, EnumSet<SecurityPermission>> 
cachePermissions() {
             return Collections.emptyMap();
         }
 
         /** {@inheritDoc} */
-        @Override public Map<String, Collection<SecurityPermission>> 
servicePermissions() {
+        @Override public Map<String, EnumSet<SecurityPermission>> 
servicePermissions() {
             return Collections.emptyMap();
         }
 
         /** {@inheritDoc} */
-        @Nullable @Override public Collection<SecurityPermission> 
systemPermissions() {
+        @Nullable @Override public EnumSet<SecurityPermission> 
systemPermissions() {
             return null;
         }
     }
diff --git a/modules/platforms/cpp/core-test/config/compute-security.xml 
b/modules/platforms/cpp/core-test/config/compute-security.xml
index e156fe4454f..2cbce8d2839 100644
--- a/modules/platforms/cpp/core-test/config/compute-security.xml
+++ b/modules/platforms/cpp/core-test/config/compute-security.xml
@@ -58,14 +58,9 @@
                     <constructor-arg name="pwd" value="pwd" />
                     <constructor-arg name="perms">
                         <bean 
class="org.apache.ignite.plugin.security.SecurityBasicPermissionSet">
-                            <property name="systemPermissions">
-                                <util:list 
value-type="org.apache.ignite.plugin.security.SecurityPermission">
-                                    <value>JOIN_AS_SERVER</value>
-                                    <value>CACHE_CREATE</value>
-                                </util:list>
-                            </property>
+                            <property name="systemPermissions" 
ref="system-permissions"/>
                             <property name="taskPermissions">
-                                <util:map map-class="java.util.HashMap" 
key-type="java.lang.String" value-type="java.util.Collection">
+                                <util:map map-class="java.util.HashMap" 
key-type="java.lang.String" value-type="java.util.EnumSet">
                                     <entry key="AllowedCallable" 
value-ref="task-execute-permission"/>
                                     <entry key="AllowedRunnable" 
value-ref="task-execute-permission"/>
                                 </util:map>
@@ -81,7 +76,20 @@
         </property>
     </bean>
 
-    <util:list id="task-execute-permission" 
value-type="org.apache.ignite.plugin.security.SecurityPermission">
-        <value>TASK_EXECUTE</value>
-    </util:list>
+    <bean id="task-execute-permission" class="java.util.EnumSet" 
factory-method="copyOf">
+        <constructor-arg>
+            <list>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.TASK_EXECUTE"/>
+            </list>
+        </constructor-arg>
+    </bean>
+
+    <bean id="system-permissions" class="java.util.EnumSet" 
factory-method="copyOf">
+        <constructor-arg>
+            <list>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER"/>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.CACHE_CREATE"/>
+            </list>
+        </constructor-arg>
+    </bean>
 </beans>
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-security.xml
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-security.xml
index 164ffde3379..c5195ddde59 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-security.xml
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-security.xml
@@ -33,14 +33,9 @@
                     <constructor-arg name="pwd" value="pwd" />
                     <constructor-arg name="perms">
                         <bean 
class="org.apache.ignite.plugin.security.SecurityBasicPermissionSet">
-                            <property name="systemPermissions">
-                                <util:list 
value-type="org.apache.ignite.plugin.security.SecurityPermission">
-                                    <value>JOIN_AS_SERVER</value>
-                                    <value>CACHE_CREATE</value>
-                                </util:list>
-                            </property>
+                            <property name="systemPermissions" 
ref="system-permissions"/>
                             <property name="taskPermissions">
-                                <util:map map-class="java.util.HashMap" 
key-type="java.lang.String" value-type="java.util.Collection">
+                                <util:map map-class="java.util.HashMap" 
key-type="java.lang.String" value-type="java.util.EnumSet">
                                     <entry 
key="Apache.Ignite.Core.Tests.Compute.ExecuteAllowedTask" 
value-ref="task-execute-permission"/>
                                     <entry 
key="Apache.Ignite.Core.Tests.Compute.ExecuteAllowedFunction" 
value-ref="task-execute-permission"/>
                                     <entry 
key="Apache.Ignite.Core.Tests.Compute.ExecuteAllowedCallable" 
value-ref="task-execute-permission"/>
@@ -59,12 +54,29 @@
         </property>
     </bean>
 
-    <util:list id="task-execute-permission" 
value-type="org.apache.ignite.plugin.security.SecurityPermission">
-        <value>TASK_EXECUTE</value>
-    </util:list>
+    <bean id="system-permissions" class="java.util.EnumSet" 
factory-method="copyOf">
+        <constructor-arg>
+            <list>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER"/>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.CACHE_CREATE"/>
+            </list>
+        </constructor-arg>
+    </bean>
 
-    <util:list id="task-execute-cancel-permission" 
value-type="org.apache.ignite.plugin.security.SecurityPermission">
-        <value>TASK_EXECUTE</value>
-        <value>TASK_CANCEL</value>
-    </util:list>
+    <bean id="task-execute-permission" class="java.util.EnumSet" 
factory-method="copyOf">
+        <constructor-arg>
+            <list>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.TASK_EXECUTE"/>
+            </list>
+        </constructor-arg>
+    </bean>
+
+    <bean id="task-execute-cancel-permission" class="java.util.EnumSet" 
factory-method="copyOf">
+        <constructor-arg>
+            <list>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.TASK_EXECUTE"/>
+                <util:constant 
static-field="org.apache.ignite.plugin.security.SecurityPermission.TASK_CANCEL"/>
+            </list>
+        </constructor-arg>
+    </bean>
 </beans>

Reply via email to