From e3dea6e428f38fd5579003b21fa61aee2846bf5e Mon Sep 17 00:00:00 2001 From: Sam Corbett Date: Fri, 13 Jan 2017 12:06:32 +0000 Subject: [PATCH 1/2] Include a policy's id in its toString --- .../java/org/apache/brooklyn/core/policy/AbstractPolicy.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/brooklyn/core/policy/AbstractPolicy.java b/core/src/main/java/org/apache/brooklyn/core/policy/AbstractPolicy.java index 3af81766b8..be1db7b89d 100644 --- a/core/src/main/java/org/apache/brooklyn/core/policy/AbstractPolicy.java +++ b/core/src/main/java/org/apache/brooklyn/core/policy/AbstractPolicy.java @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.MoreObjects; import com.google.common.base.Objects; /** @@ -117,7 +118,8 @@ public RelationSupportInternal relations() { @Override public String toString() { - return Objects.toStringHelper(getClass()) + return MoreObjects.toStringHelper(getClass()) + .add("id", getId()) .add("name", name) .add("running", isRunning()) .toString(); From 1c94979a563230245e12d9ba4e7539f3abab8c48 Mon Sep 17 00:00:00 2001 From: Sam Corbett Date: Fri, 13 Jan 2017 12:14:02 +0000 Subject: [PATCH 2/2] AbstractMemberTrackingPolicy does not call MEMBER_ADDED when rebinding --- .../AbstractMembershipTrackingPolicy.java | 9 ++- .../mgmt/rebind/RebindDynamicGroupTest.java | 13 ++- .../MembershipTrackingPolicyRebindTest.java | 81 +++++++++++++++++++ 3 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 core/src/test/java/org/apache/brooklyn/entity/group/MembershipTrackingPolicyRebindTest.java diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java index 6d053adf02..021c336413 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java +++ b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java @@ -206,8 +206,13 @@ protected void subscribeToGroup(final Group group) { } }); } - - for (Entity it : group.getMembers()) { onEntityEvent(EventType.ENTITY_ADDED, it); } + + // The policy will have already fired events for its members. + if (!isRebinding()) { + for (Entity it : group.getMembers()) { + onEntityEvent(EventType.ENTITY_ADDED, it); + } + } } protected void unsubscribeFromGroup() { diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindDynamicGroupTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindDynamicGroupTest.java index 2f9bc8e71e..8f2c50cd4c 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindDynamicGroupTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindDynamicGroupTest.java @@ -24,7 +24,6 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.mgmt.rebind.RebindEntityTest.MyEntity; import org.apache.brooklyn.entity.group.DynamicGroup; import org.apache.brooklyn.test.Asserts; @@ -42,26 +41,24 @@ public void testRestoresDynamicGroup() throws Exception { origApp.createAndManageChild(EntitySpec.create(MyEntity.class)); origApp.createAndManageChild(EntitySpec.create(DynamicGroup.class) .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(MyEntity.class))); - newApp = rebind(); final DynamicGroup newG = (DynamicGroup) Iterables.find(newApp.getChildren(), Predicates.instanceOf(DynamicGroup.class)); final MyEntity newE = (MyEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(MyEntity.class)); // Rebound group should contain same members as last time - assertGroupMemebers(newG, ImmutableSet.of(newE)); + assertGroupMembers(newG, ImmutableSet.of(newE)); // And should detect new members that match the filter final MyEntity newE2 = newApp.createAndManageChild(EntitySpec.create(MyEntity.class)); - Asserts.succeedsEventually(new Runnable() { @Override public void run() { - assertGroupMemebers(newG, ImmutableSet.of(newE, newE2)); + assertGroupMembers(newG, ImmutableSet.of(newE, newE2)); }}); } - private void assertGroupMemebers(DynamicGroup group, Collection expected) { + private void assertGroupMembers(DynamicGroup group, Collection expected) { assertEquals(Sets.newHashSet(group.getMembers()), ImmutableSet.copyOf(expected)); - assertEquals(group.getMembers().size(), expected.size(), "members="+group.getMembers()); + assertEquals(group.getMembers().size(), expected.size(), "members=" + group.getMembers()); } - + } diff --git a/core/src/test/java/org/apache/brooklyn/entity/group/MembershipTrackingPolicyRebindTest.java b/core/src/test/java/org/apache/brooklyn/entity/group/MembershipTrackingPolicyRebindTest.java new file mode 100644 index 0000000000..9135ec1be7 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/entity/group/MembershipTrackingPolicyRebindTest.java @@ -0,0 +1,81 @@ +/* + * 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.entity.group; + +import static org.testng.Assert.assertEquals; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.policy.PolicySpec; +import org.apache.brooklyn.core.mgmt.rebind.RebindEntityTest; +import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp; +import org.apache.brooklyn.test.Asserts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; + +public class MembershipTrackingPolicyRebindTest extends RebindTestFixtureWithApp { + + private static final Logger LOG = LoggerFactory.getLogger(MembershipTrackingPolicyRebindTest.class); + private static final AtomicInteger ADDITIONS_COUNTER = new AtomicInteger(); + + @BeforeMethod + @Override + public void setUp() throws Exception { + super.setUp(); + ADDITIONS_COUNTER.set(0); + } + + @Test + public void testMemberAddedNotFiredAfterRebind() throws Exception { + DynamicGroup group = origApp.createAndManageChild(EntitySpec.create(DynamicGroup.class) + .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(RebindEntityTest.MyEntity.class))); + + origApp.policies().add(PolicySpec.create(Tracker.class) + .displayName("testMemberAddedNotFiredAfterRebind") + .configure(AbstractMembershipTrackingPolicy.GROUP, group)); + origApp.createAndManageChild(EntitySpec.create(RebindEntityTest.MyEntity.class)); + + Runnable assertOneAddition = new Runnable() { + @Override + public void run() { + assertEquals(ADDITIONS_COUNTER.get(), 1); + } + }; + Asserts.succeedsEventually(assertOneAddition); + rebind(); + Asserts.succeedsContinually(assertOneAddition); + } + + public static class Tracker extends AbstractMembershipTrackingPolicy { + @Override + protected void onEntityAdded(Entity member) { + super.onEntityAdded(member); + int count = ADDITIONS_COUNTER.incrementAndGet(); + LOG.info("{} notified of new member: {} (count={})", + new Object[]{this, member, count}); + } + } +}