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(); + } + } }