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 04e8e7d  add a post-init hook interface for entities
     new f6c290f  Merge pull request #1114 from ahgittin/post-init
04e8e7d is described below

commit 04e8e7d47d588384fb28c06dea059aa28d11ed87
Author: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
AuthorDate: Mon Oct 5 20:09:28 2020 +0100

    add a post-init hook interface for entities
---
 .../brooklyn/core/entity/AbstractEntity.java       |  8 ++++
 .../core/entity/EntityPostInitializable.java       | 32 +++++++++++++++
 .../core/objs/proxy/InternalEntityFactory.java     | 16 ++++----
 .../core/entity/EntityInitializersTest.java        | 47 ++++++++++++++++++++++
 4 files changed, 95 insertions(+), 8 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 fa7cecd..a3b95d4 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
@@ -1302,6 +1302,14 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
 
     /**
      * Default entity initialization sets ID sensors and calls {@link 
#initEnrichers()}.
+     * <p>
+     * See superclass Javadoc for more info.
+     * <p>
+     * Note that this is invoked before {@link 
org.apache.brooklyn.api.entity.EntityInitializer} instances are called,
+     * before policies and enrichers are added,
+     * before descendants are initialized,
+     * before {@link EntityPostInitializable#postInit()},
+     * and before this entity is managed.
      */
     @Override
     public void init() {
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/entity/EntityPostInitializable.java
 
b/core/src/main/java/org/apache/brooklyn/core/entity/EntityPostInitializable.java
new file mode 100644
index 0000000..5c57388
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/entity/EntityPostInitializable.java
@@ -0,0 +1,32 @@
+/*
+ * 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.brooklyn.core.entity;
+
+public interface EntityPostInitializable {
+
+    /**
+     * Invoked on an {@link org.apache.brooklyn.api.entity.Entity} after 
setting its config,
+     * invoking its {@link 
org.apache.brooklyn.core.objs.AbstractBrooklynObject#init()} method,
+     * descendants initialized and any {@link #postInit()} method on those 
invoked,
+     * and any associated {@link 
org.apache.brooklyn.api.entity.EntityInitializer} instances applied.
+     * <p>
+     * See {@link AbstractEntity#init()} for more detail. */
+    void postInit();
+
+}
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
 
b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
index 28208cc..166bf0f 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
@@ -40,11 +40,7 @@ import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.EnricherSpec;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigConstraints;
-import org.apache.brooklyn.core.entity.AbstractApplication;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityDynamicType;
-import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.*;
 import org.apache.brooklyn.core.mgmt.BrooklynTags;
 import org.apache.brooklyn.core.mgmt.BrooklynTags.NamedStringTag;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
@@ -146,7 +142,7 @@ public class InternalEntityFactory extends InternalFactory {
      * fully initialized ({@link AbstractEntity#init()} invoked) and ready for
      * management -- commonly the caller will next call 
      * {@link Entities#manage(Entity)} (if it's in a managed application)
-     * or {@link 
Entities#startManagement(org.apache.brooklyn.api.entity.Application, 
org.apache.brooklyn.api.management.ManagementContext)}
+     * or {@link 
Entities#startManagement(org.apache.brooklyn.api.entity.Application, 
org.apache.brooklyn.api.mgmt.ManagementContext)}
      * (if it's an application) */
     public <T extends Entity> T createEntity(EntitySpec<T> spec, 
Optional<String> entityId) {
         /* Order is important here. Changed Jul 2014 when supporting children 
in spec.
@@ -363,16 +359,20 @@ public class InternalEntityFactory extends 
InternalFactory {
                     // they could be done in parallel, but OTOH initializers 
should be very quick
                     initEntityAndDescendants(child.getId(), 
entitiesByEntityId, specsByEntityId);
                 }
+
+                if (entity instanceof EntityPostInitializable) {
+                    ((EntityPostInitializable)entity).postInit();
+                }
             }
         }).build());
     }
     
     /**
      * Constructs an entity, i.e. instantiate the actual class given a spec,
-     * and sets the entity's proxy. Used by this factory to {@link 
#createEntity(EntitySpec)}
+     * and sets the entity's proxy. Used by this factory to {@link 
#createEntity(EntitySpec, Optional<String>)}
      * and also used during rebind.
      * <p> 
-     * If {@link EntitySpec#id(String)} was set then uses that to override the 
entity's id, 
+     * If the entityId is provided, then uses that to override the entity's id,
      * but that behaviour is deprecated.
      * <p>
      * The new-style no-arg constructor is preferred, and   
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/entity/EntityInitializersTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/entity/EntityInitializersTest.java
index 579e93c..f7bdd0c 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/entity/EntityInitializersTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/entity/EntityInitializersTest.java
@@ -18,6 +18,10 @@
  */
 package org.apache.brooklyn.core.entity;
 
+import java.util.List;
+import org.apache.brooklyn.api.entity.*;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.testng.Assert;
 import static org.testng.Assert.assertEquals;
 
 import java.util.Map;
@@ -64,4 +68,47 @@ public class EntityInitializersTest extends 
BrooklynAppUnitTestSupport {
     private Object resolve(Map<?,?> config, ConfigKey<?> key) {
         return EntityInitializers.resolve(ConfigBag.newInstance(config), key, 
app.getExecutionContext()); 
     }
+
+    static List<String> sequenceMessages = MutableList.of();
+
+    @ImplementedBy(InitSequenceTestEntityImpl.class)
+    public static interface InitSequenceTestEntity extends Entity, 
EntityPostInitializable {
+        final ConfigKey<String> NAME = ConfigKeys.newStringConfigKey("name");
+    }
+    public static class InitSequenceTestEntityImpl extends AbstractEntity 
implements InitSequenceTestEntity {
+
+        @Override
+        public void init() {
+            super.init();
+            sequenceMessages.add(config().get(NAME)+":"+"init");
+        }
+
+        @Override
+        public void postInit() {
+            sequenceMessages.add(config().get(NAME)+":"+"postInit");
+        }
+    }
+
+    public static class InitSequenceEntityInitializer implements 
EntityInitializer {
+        @Override
+        public void apply(EntityLocal entity) {
+            
sequenceMessages.add(entity.config().get(InitSequenceTestEntity.NAME)+":"+"initializer");
+        }
+    }
+
+    @Test
+    public void testSequence() {
+        sequenceMessages.clear();
+        try {
+            
mgmt.getEntityManager().createEntity(EntitySpec.create(InitSequenceTestEntity.class)
+                    .addInitializer(InitSequenceEntityInitializer.class)
+                    .configure(InitSequenceTestEntity.NAME, "A")
+                    .child(EntitySpec.create(InitSequenceTestEntity.class)
+                            
.addInitializer(InitSequenceEntityInitializer.class)
+                            .configure(InitSequenceTestEntity.NAME, "B")));
+            Assert.assertEquals(MutableList.of("A:init", "A:initializer", 
"B:init", "B:initializer", "B:postInit", "A:postInit"), sequenceMessages);
+        } finally {
+            sequenceMessages.clear();
+        }
+    }
 }

Reply via email to