Repository: ignite
Updated Branches:
  refs/heads/master 9d9c237d0 -> 1382df19f


IGNITE-9365 - Attribute based affinity backup filter implementation - Fixes 
#4719

Signed-off-by: Valentin Kulichenko <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1382df19
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1382df19
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1382df19

Branch: refs/heads/master
Commit: 1382df19fa49a89714c707b04ec4920802a6064d
Parents: 9d9c237
Author: Dave Harvey <[email protected]>
Authored: Fri Sep 21 15:53:00 2018 -0700
Committer: Valentin Kulichenko <[email protected]>
Committed: Fri Sep 21 15:53:00 2018 -0700

----------------------------------------------------------------------
 ...lusterNodeAttributeAffinityBackupFilter.java | 141 +++++++++----------
 ...ityFunctionBackupFilterAbstractSelfTest.java |   8 +-
 ...deAttributeAffinityBackupFilterSelfTest.java |  15 +-
 3 files changed, 78 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1382df19/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilter.java
 
b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilter.java
index 7b75dbe..3949a28 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilter.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilter.java
@@ -17,16 +17,15 @@
 
 package org.apache.ignite.cache.affinity.rendezvous;
 
-import java.io.Serializable;
 import java.util.List;
 import java.util.Objects;
-
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.lang.IgniteBiPredicate;
 
 /**
- * This class can be used as a {@link 
RendezvousAffinityFunction#affinityBackupFilter } to create 
- * cache templates in Spring that force each partition's primary and backup to 
different hardware which 
+ * This class can be used as a {@link 
RendezvousAffinityFunction#affinityBackupFilter } to create
+ * cache templates in Spring that force each partition's primary and backup to 
different hardware which
  * is not expected to fail simultaneously, e.g., in AWS, to different 
"availability zones".  This
  * is a per-partition selection, and different partitions may choose different 
primaries.
  * <p>
@@ -35,8 +34,8 @@ import org.apache.ignite.lang.IgniteBiPredicate;
  * <p>
  * A list of node attributes to compare is provided on construction.  Note: 
"All cluster nodes,
  * on startup, automatically register all the environment and system 
properties as node attributes."
- * <p> 
- * This class is constructed with a array of node attribute names, and a 
candidate node will be rejected if *any* of the 
+ * <p>
+ * This class is constructed with a array of node attribute names, and a 
candidate node will be rejected if *any* of the
  * previously selected nodes for a partition have the identical values for 
*all* of those attributes on the candidate node.
  * Another way to understand this is the set of attribute values defines the 
key of a group into which a node is placed,
  * an the primaries and backups for a partition cannot share nodes in the same 
group.   A null attribute is treated  as
@@ -48,87 +47,85 @@ import org.apache.ignite.lang.IgniteBiPredicate;
  * </pre>
  * <h2 class="header">Spring Example</h2>
  * Create a partitioned cache template plate with 1 backup, where the backup 
will not be placed in the same availability zone
- * as the primary.   Note: This example requires that the environment variable 
"AVAILABILTY_ZONE" be set appropriately on 
- * each node via some means external to Ignite.  On AWS, some nodes might have 
AVAILABILTY_ZONE=us-east-1a and others 
- * AVAILABILTY_ZONE=us-east-1b. 
+ * as the primary.   Note: This example requires that the environment variable 
"AVAILABILTY_ZONE" be set appropriately on
+ * each node via some means external to Ignite.  On AWS, some nodes might have 
AVAILABILTY_ZONE=us-east-1a and others
+ * AVAILABILTY_ZONE=us-east-1b.
  * <pre name="code" class="xml">
- * 
- * &lt;property name="cacheConfiguration"&gt; 
- *     &lt;list&gt; 
- *         &lt;bean id="cache-template-bean" abstract="true" 
class="org.apache.ignite.configuration.CacheConfiguration"&gt; 
- *             &lt;property name="name" 
value="JobcaseDefaultCacheConfig*"/&gt; 
- *             &lt;property name="cacheMode" value="PARTITIONED" /&gt; 
- *             &lt;property name="backups" value="1" /&gt; 
+ * &lt;property name="cacheConfiguration"&gt;
+ *     &lt;list&gt;
+ *         &lt;bean id="cache-template-bean" abstract="true" 
class="org.apache.ignite.configuration.CacheConfiguration"&gt;
+ *             &lt;property name="name" value="JobcaseDefaultCacheConfig*"/&gt;
+ *             &lt;property name="cacheMode" value="PARTITIONED" /&gt;
+ *             &lt;property name="backups" value="1" /&gt;
  *             &lt;property name="affinity"&gt;
  *                 &lt;bean 
class="org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction"&gt;
  *                     &lt;property name="affinityBackupFilter"&gt;
  *                         &lt;bean 
class="org.apache.ignite.cache.affinity.rendezvous.ClusterNodeAttributeAffinityBackupFilter"&gt;
- *                            &lt;constructor-arg&gt;
- *                                &lt;array value-type="java.lang.String"&gt;
+ *                             &lt;constructor-arg&gt;
+ *                                 &lt;array value-type="java.lang.String"&gt;
  *                                     &lt;!-- Backups must go to different 
AZs --&gt;
  *                                     
&lt;value&gt;AVAILABILITY_ZONE&lt;/value&gt;
- *                                &lt;/array&gt;
- *                            &lt;/constructor-arg&gt;                         
          
+ *                                 &lt;/array&gt;
+ *                             &lt;/constructor-arg&gt;
  *                         &lt;/bean&gt;
  *                     &lt;/property&gt;
- *                &lt;/bean&gt;
+ *                 &lt;/bean&gt;
  *             &lt;/property&gt;
- *        &lt;/bean&gt; 
- *    &lt;/list&gt; 
- *  &lt;/property&gt; 
+ *         &lt;/bean&gt;
+ *     &lt;/list&gt;
+ * &lt;/property&gt;
  * </pre>
- * 
- * With more backups, multiple properties, e.g., SITE, ZONE,  could be used to 
force backups to different subgroups. 
+ * <p>
+ * With more backups, multiple properties, e.g., SITE, ZONE,  could be used to 
force backups to different subgroups.
  */
-public class ClusterNodeAttributeAffinityBackupFilter implements 
IgniteBiPredicate<ClusterNode, List<ClusterNode>>, Serializable {
-   /**
-    * 
-    */
-   private static final long serialVersionUID = 1L;
+public class ClusterNodeAttributeAffinityBackupFilter implements 
IgniteBiPredicate<ClusterNode, List<ClusterNode>> {
+    /** */
+    private static final long serialVersionUID = 1L;
+
+    /** Attribute names. */
+    private final String[] attributeNames;
+
+    /**
+     * @param attributeNames The list of attribute names for the set of 
attributes to compare. Must be at least one.
+     */
+    ClusterNodeAttributeAffinityBackupFilter(String... attributeNames) {
+        A.ensure(attributeNames.length > 0, "attributeNames.length > 0");
+
+        this.attributeNames = attributeNames;
+    }
+
+    /**
+     * Defines a predicate which returns {@code true} if a node is acceptable 
for a backup
+     * or {@code false} otherwise. An acceptable node is one where its set of 
attribute values
+     * is not exact match with any of the previously selected nodes.  If an 
attribute does not
+     * exist on exactly one node of a pair, then the attribute does not match. 
 If the attribute
+     * does not exist both nodes of a pair, then the attribute matches.
+     * <p>
+     * Warning:  if an attribute is specified that does not exist on any node, 
then no backups
+     * will be created, because all nodes will match.
+     * <p>
+     *
+     * @param candidate          A node that is a candidate for becoming a 
backup node for a partition.
+     * @param previouslySelected A list of primary/backup nodes already chosen 
for a partition.
+     *                           The primary is first.
+     */
+    @Override public boolean apply(ClusterNode candidate, List<ClusterNode> 
previouslySelected) {
+        for (ClusterNode node : previouslySelected) {
+            boolean match = true;
 
-   
-   final String [] attributeNames;
+            for (String attribute : attributeNames) {
+                if (!Objects.equals(candidate.attribute(attribute), 
node.attribute(attribute))) {
+                    match = false;
 
-   /*
-    * @param attributeNames - the list of attribute names for the set of 
attributes to compare. Must be at least one.
-    */
-   ClusterNodeAttributeAffinityBackupFilter(String[] attributeNames)
-   {
-      assert attributeNames.length > 0;
-      
-      this.attributeNames = attributeNames;
-   }
+                    break;
+                }
+            }
 
-   /**
-    * Defines a predicate which returns {@code true} if a node is acceptable 
for a backup
-    * or {@code false} otherwise. An acceptable node is one where its set of 
attribute values
-    * is not exact match with any of the previously selected nodes.  If an 
attribute does not
-    * exist on exactly one node of a pair, then the attribute does not match.  
If the attribute
-    * does not exist both nodes of a pair, then the attribute matches.
-    * <p>
-    * Warning:  if an attribute is specified that does not exist on any node, 
then no backups
-    * will be created, because all nodes will match.
-    * <p>
-    * @param candidate A node that is a candidate for becoming a backup node 
for a partition.
-    * @param previouslySelected A list of primary/backup nodes already chosen 
for a partition.  
-    * The primary is first.
-    */
-   @Override
-   public boolean apply(ClusterNode candidate, List<ClusterNode> 
previouslySelected) {
+            if (match)
+                return false;
+        }
 
-      for (ClusterNode node : previouslySelected) {
-         boolean match = true;
-         
-         for (String attribute : attributeNames) {
-               if (!Objects.equals(candidate.attribute(attribute), 
node.attribute(attribute)) ) {
-                  match = false;
-                  break;
-               }         
-         }
-         if (match)
-            return false;   
-      }
-      return true;
-   }
+        return true;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1382df19/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
index 9e04dbb..74add0c 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
@@ -87,7 +87,7 @@ public abstract class 
AffinityFunctionBackupFilterAbstractSelfTest extends GridC
                 return backupAssignedAttribute.get(nodeAttributeVal).equals(0);
             }
         };
-     
+
     /**
      * @param nodes List of cluster nodes.
      * @return Statistic.
@@ -233,7 +233,7 @@ public abstract class 
AffinityFunctionBackupFilterAbstractSelfTest extends GridC
             stopAllGrids();
         }
     }
-    
+
     /* Different affinityBackupFilters have different goals */
     protected int expectedNodesForEachPartition() {
        return backups + 1;
@@ -249,7 +249,7 @@ public abstract class 
AffinityFunctionBackupFilterAbstractSelfTest extends GridC
         int partCnt = aff.partitions();
 
         IgniteCache<Object, Object> cache = grid(0).cache(DEFAULT_CACHE_NAME);
-        
+
         for (int i = 0; i < partCnt; i++) {
             Collection<ClusterNode> nodes = 
affinity(cache).mapKeyToPrimaryAndBackups(i);
 
@@ -264,4 +264,4 @@ public abstract class 
AffinityFunctionBackupFilterAbstractSelfTest extends GridC
             assertEquals(stat.get("C"), new Integer(1));
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1382df19/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilterSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilterSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilterSelfTest.java
index f0e8720..2c1ddbf 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilterSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/ClusterNodeAttributeAffinityBackupFilterSelfTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.ignite.cache.affinity.rendezvous;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import 
org.apache.ignite.cache.affinity.AffinityFunctionBackupFilterAbstractSelfTest;
 
@@ -40,19 +36,18 @@ public class 
ClusterNodeAttributeAffinityBackupFilterSelfTest extends AffinityFu
     /** {@inheritDoc} */
     @Override protected AffinityFunction 
affinityFunctionWithAffinityBackupFilter(String attributeName) {
         RendezvousAffinityFunction aff = new RendezvousAffinityFunction(false);
-        
+
         String[] stringArray = new String[1];
-       
+
         stringArray[0] = attributeName;
-        
+
         aff.setAffinityBackupFilter(new 
ClusterNodeAttributeAffinityBackupFilter(stringArray));
 
         return aff;
     }
-    
+
     /** {@inheritDoc} */
-    @Override
-    protected int expectedNodesForEachPartition() {
+    @Override protected int expectedNodesForEachPartition() {
        return 3;
     }
 }

Reply via email to