You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by iu...@apache.org on 2022/07/14 13:49:32 UTC

[brooklyn-server] branch master updated: allow to specify an ancestor root in which a dynamic group should search or scan

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

iuliana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git


The following commit(s) were added to refs/heads/master by this push:
     new 704c63e618 allow to specify an ancestor root in which a dynamic group should search or scan
     new 0ddde15be3 Merge pull request #1340 from ahgittin/dynamic-group-ancestor
704c63e618 is described below

commit 704c63e6182352f0b2ec01ffe25edb85d4ad9520
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Thu Jul 14 14:08:23 2022 +0100

    allow to specify an ancestor root in which a dynamic group should search or scan
---
 .../brooklyn/core/entity/AbstractEntity.java       |  1 +
 .../brooklyn/core/entity/EntityPredicates.java     | 24 ++++++++++++++++++++++
 .../apache/brooklyn/entity/group/DynamicGroup.java |  4 ++++
 .../brooklyn/entity/group/DynamicGroupImpl.java    | 18 ++++++++++++----
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 8534e262b4..c047ee6ecb 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -1198,6 +1198,7 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     // TODO can this be replaced with config().set ?
     // seems only used for configure(Map) -- where validation might want to be skipped;
     // and also in a couple places where i don't think it matters
+    // (difference is that this one skips the onChanging and onChanged calls)
     @SuppressWarnings("unchecked")
     public <T> T setConfigEvenIfOwned(ConfigKey<T> key, T val) {
         return (T) configsInternal.setConfig(key, val);
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityPredicates.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityPredicates.java
index 14e02d7479..496cd48e95 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityPredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityPredicates.java
@@ -415,6 +415,30 @@ public class EntityPredicates {
         };
     }
 
+    /**
+     * Returns a predicate that determines if a given entity is a descendant of (or equal to) this {@code ancestor}.
+     */
+    public static Predicate<Entity> isDescendantOf(final Entity ancestor) {
+        return new IsDescendantOf(ancestor);
+    }
+
+    protected static class IsDescendantOf implements SerializablePredicate<Entity> {
+        protected final Entity ancestor;
+        protected IsDescendantOf(Entity ancestor) {
+            this.ancestor = ancestor;
+        }
+        @Override
+        public boolean apply(@Nullable Entity input) {
+            if (input==null) return false;
+            if (Objects.equal(input, ancestor)) return true;
+            return apply(input.getParent());
+        }
+        @Override
+        public String toString() {
+            return "isDescendantOf("+ancestor+")";
+        }
+    }
+
     // ---------------------------
     
     public static Predicate<Entity> isMemberOf(final Group group) {
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
index 478729746f..a4fdace6a9 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
@@ -46,6 +46,10 @@ public interface DynamicGroup extends AbstractGroup {
             "dynamicgroup.entityfilter", 
             "Filter for entities which will automatically be in the group");
 
+    ConfigKey<Entity> ANCESTOR = ConfigKeys.newConfigKey(Entity.class,
+            "dynamicgroup.ancestor",
+            "Ancestor (or application) under which to search, or null to use containing application");
+
     AttributeSensor<Boolean> RUNNING = Sensors.newBooleanSensor(
             "dynamicgroup.running", "Whether the entity is running, and will automatically update group membership");
 
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroupImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroupImpl.java
index bcf6029337..abeaaeeacf 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroupImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroupImpl.java
@@ -57,7 +57,6 @@ public class DynamicGroupImpl extends AbstractGroupImpl implements DynamicGroup
 
     @Override
     public void setEntityFilter(Predicate<? super Entity> filter) {
-        // TODO Sould this be "evenIfOwned"?
         setConfigEvenIfOwned(ENTITY_FILTER, filter);
         rescanEntities();
     }
@@ -77,11 +76,22 @@ public class DynamicGroupImpl extends AbstractGroupImpl implements DynamicGroup
         if (entityFilter == null) {
             entityFilter = Predicates.alwaysFalse();
         }
+        Entity ancestor = getAncestorToScan();
+        Predicate<Entity> ancestorFilter;
+        if (ancestor==null) ancestorFilter = EntityPredicates.applicationIdEqualTo(getApplicationId());
+        else if (ancestor.getParent()==null) ancestorFilter = EntityPredicates.applicationIdEqualTo(ancestor.getId());
+        else ancestorFilter = EntityPredicates.isDescendantOf(ancestor);
         return Predicates.and(
-                EntityPredicates.applicationIdEqualTo(getApplicationId()),
+                ancestorFilter,
                 entityFilter);
     }
 
+    protected Entity getAncestorToScan() {
+        Entity ancestor = getConfig(ANCESTOR);
+        if (ancestor==null) return getApplication();
+        return ancestor;
+    }
+
     private boolean isRunning() {
         return Boolean.TRUE.equals(getAttribute(RUNNING));
     }
@@ -200,7 +210,7 @@ public class DynamicGroupImpl extends AbstractGroupImpl implements DynamicGroup
                 if (log.isDebugEnabled()) log.debug("{} not scanning for children: stopped", this);
                 return;
             }
-            if (getApplication() == null) {
+            if (getAncestorToScan() == null) {
                 BrooklynLogging.log(log, BrooklynLogging.levelDependingIfReadOnly(this, LoggingLevel.WARN, LoggingLevel.TRACE, LoggingLevel.TRACE),
                     "{} not (yet) scanning for children: no application defined", this);
                 return;
@@ -209,7 +219,7 @@ public class DynamicGroupImpl extends AbstractGroupImpl implements DynamicGroup
             Collection<Entity> currentMembers = getMembers();
             Collection<Entity> toRemove = Sets.newLinkedHashSet(currentMembers);
 
-            final Iterable<Entity> unfiltered = Entities.descendantsAndSelf(getApplication());
+            final Iterable<Entity> unfiltered = Entities.descendantsAndSelf(getAncestorToScan());
             log.debug("{} filtering {} with {}", new Object[]{this, unfiltered, entityFilter()});
             for (Entity it : Iterables.filter(unfiltered, entityFilter())) {
                 toRemove.remove(it);