Repository: brooklyn-library Updated Branches: refs/heads/master 732d73ac2 -> 77f898433
Adds loadBalancer.changeServerPool Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/afc33398 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/afc33398 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/afc33398 Branch: refs/heads/master Commit: afc333985825c6fd370267997a86c8da6a5099d5 Parents: 732d73a Author: Aled Sage <aled.s...@gmail.com> Authored: Wed Feb 14 21:17:29 2018 +0000 Committer: Aled Sage <aled.s...@gmail.com> Committed: Mon Feb 19 21:59:10 2018 +0000 ---------------------------------------------------------------------- .../entity/proxy/AbstractControllerImpl.java | 36 ++++++++++++++++++-- .../AbstractNonProvisionedControllerImpl.java | 36 ++++++++++++++++++-- .../brooklyn/entity/proxy/LoadBalancer.java | 5 +++ .../entity/proxy/LoadBalancerClusterImpl.java | 15 ++++++++ .../proxy/AbstractAbstractControllerTest.java | 22 ++++++++++++ 5 files changed, 110 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/afc33398/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java index 34c324e..bd5bc15 100644 --- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java +++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java @@ -33,6 +33,7 @@ import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.core.annotation.EffectorParam; import org.apache.brooklyn.core.entity.Attributes; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.EntityInternal; @@ -148,9 +149,25 @@ public abstract class AbstractControllerImpl extends SoftwareProcessImpl impleme protected void removeServerPoolMemberTrackingPolicy() { if (serverPoolMemberTrackerPolicy != null) { policies().remove(serverPoolMemberTrackerPolicy); + serverPoolMemberTrackerPolicy = null; } } + protected boolean hasServerPoolMemberTrackingPolicy() { + if (serverPoolMemberTrackerPolicy != null) return true; + + // On rebind, might not have set the field yet + for (Policy p: policies()) { + if (p instanceof ServerPoolMemberTrackerPolicy) { + LOG.info(this+" picking up "+p+" as the tracker (already set, often due to rebind)"); + serverPoolMemberTrackerPolicy = (ServerPoolMemberTrackerPolicy) p; + return true; + } + } + + return false; + } + public static class ServerPoolMemberTrackerPolicy extends AbstractMembershipTrackingPolicy { @Override protected void onEntityEvent(EventType type, Entity entity) { @@ -411,8 +428,9 @@ public abstract class AbstractControllerImpl extends SoftwareProcessImpl impleme public Task<?> updateAsync() { synchronized (serverPoolAddresses) { Task<?> result = null; - if (!isActive()) updateNeeded = true; - else { + if (!isActive()) { + updateNeeded = true; + } else { updateNeeded = false; LOG.debug("Updating {} in response to changes", this); LOG.info("Updating {}, server pool targets {}", new Object[] {this, getAttribute(SERVER_POOL_TARGETS)}); @@ -425,6 +443,20 @@ public abstract class AbstractControllerImpl extends SoftwareProcessImpl impleme } } + @Override + public void changeServerPool(String groupId) { + Group newGroup = (Group) getManagementContext().getEntityManager().getEntity(groupId); + if (newGroup == null) { + throw new IllegalArgumentException("Group '"+groupId+"' not found"); + } + + config().set(SERVER_POOL, newGroup); + if (hasServerPoolMemberTrackingPolicy()) { + addServerPoolMemberTrackingPolicy(); + } + updateNeeded(); + } + protected void onServerPoolMemberChanged(Entity member) { synchronized (serverPoolAddresses) { if (LOG.isTraceEnabled()) LOG.trace("For {}, considering membership of {} which is in locations {}", http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/afc33398/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java index 15cd94d..24d57fa 100644 --- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java +++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java @@ -39,6 +39,7 @@ import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.feed.ConfigToAttributes; import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy; import org.apache.brooklyn.entity.proxy.AbstractControllerImpl.MapAttribute; +import org.apache.brooklyn.entity.proxy.AbstractControllerImpl.ServerPoolMemberTrackerPolicy; import org.apache.brooklyn.util.core.task.Tasks; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; @@ -215,9 +216,25 @@ public abstract class AbstractNonProvisionedControllerImpl extends AbstractEntit protected void removeServerPoolMemberTrackingPolicy() { if (serverPoolMemberTrackerPolicy != null) { policies().remove(serverPoolMemberTrackerPolicy); + serverPoolMemberTrackerPolicy = null; } } + protected boolean hasServerPoolMemberTrackingPolicy() { + if (serverPoolMemberTrackerPolicy != null) return true; + + // On rebind, might not have set the field yet + for (Policy p: policies()) { + if (p instanceof ServerPoolMemberTrackerPolicy) { + LOG.info(this+" picking up "+p+" as the tracker (already set, often due to rebind)"); + serverPoolMemberTrackerPolicy = (ServerPoolMemberTrackerPolicy) p; + return true; + } + } + + return false; + } + public static class ServerPoolMemberTrackerPolicy extends AbstractMembershipTrackingPolicy { @Override protected void onEntityEvent(EventType type, Entity entity) { @@ -263,8 +280,9 @@ public abstract class AbstractNonProvisionedControllerImpl extends AbstractEntit public Task<?> updateAsync() { synchronized (mutex) { Task<?> result = null; - if (!isActive()) updateNeeded = true; - else { + if (!isActive()) { + updateNeeded = true; + } else { updateNeeded = false; LOG.debug("Updating {} in response to changes", this); LOG.info("Updating {}, server pool targets {}", new Object[] {this, getAttribute(SERVER_POOL_TARGETS)}); @@ -276,6 +294,20 @@ public abstract class AbstractNonProvisionedControllerImpl extends AbstractEntit } } + @Override + public void changeServerPool(String groupId) { + Group newGroup = (Group) getManagementContext().getEntityManager().getEntity(groupId); + if (newGroup == null) { + throw new IllegalArgumentException("Group '"+groupId+"' not found"); + } + + config().set(SERVER_POOL, newGroup); + if (hasServerPoolMemberTrackingPolicy()) { + addServerPoolMemberTrackingPolicy(); + } + updateNeeded(); + } + protected void onServerPoolMemberChanged(Entity member) { synchronized (mutex) { if (LOG.isTraceEnabled()) LOG.trace("For {}, considering membership of {} which is in locations {}", http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/afc33398/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java index 6ff9cb4..689f22b 100644 --- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java +++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java @@ -27,6 +27,7 @@ import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.annotation.Effector; +import org.apache.brooklyn.core.annotation.EffectorParam; import org.apache.brooklyn.core.config.BasicConfigKey; import org.apache.brooklyn.core.effector.MethodEffector; import org.apache.brooklyn.core.entity.Attributes; @@ -132,6 +133,10 @@ public interface LoadBalancer extends Entity, Startable { public static final MethodEffector<Void> UPDATE = new MethodEffector<Void>(LoadBalancer.class, "update"); + @Effector(description="Change the target server pool") + public void changeServerPool( + @EffectorParam(name="groupId") String groupId); + @Effector(description="Forces reload of the configuration") public void reload(); http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/afc33398/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancerClusterImpl.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancerClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancerClusterImpl.java index ff23089..863b7ed 100644 --- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancerClusterImpl.java +++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancerClusterImpl.java @@ -21,6 +21,7 @@ package org.apache.brooklyn.entity.proxy; import java.util.Map; import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.entity.group.DynamicClusterImpl; /** @@ -73,4 +74,18 @@ public class LoadBalancerClusterImpl extends DynamicClusterImpl implements LoadB } } } + + @Override + public void changeServerPool(String groupId) { + Group newGroup = (Group) getManagementContext().getEntityManager().getEntity(groupId); + if (newGroup == null) { + throw new IllegalArgumentException("Group '"+groupId+"' not found"); + } + + for (Entity member : getMembers()) { + if (member instanceof LoadBalancer) { + ((LoadBalancer)member).changeServerPool(groupId); + } + } + } } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/afc33398/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractAbstractControllerTest.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractAbstractControllerTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractAbstractControllerTest.java index eba82c5..a9065c5 100644 --- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractAbstractControllerTest.java +++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractAbstractControllerTest.java @@ -229,6 +229,28 @@ public abstract class AbstractAbstractControllerTest<T extends LoadBalancer> ext assertEventuallyAddressesMatch(ImmutableList.<Entity>of()); } + @Test + public void testUpdateCalledWhenServerPoolGroupSwapped() { + // Second cluster with one child + DynamicCluster cluster2 = app.addChild(EntitySpec.create(DynamicCluster.class) + .configure("initialSize", 1) + .configure("memberSpec", EntitySpec.create(TestEntity.class).impl(WebServerEntity.class))); + cluster2.start(ImmutableList.of()); + + Entity child = Iterables.getOnlyElement(cluster2.getMembers()); + child.sensors().set(WebServerEntity.HTTP_PORT, 1234); + child.sensors().set(Startable.SERVICE_UP, true); + + // Reconfigure the controller to point at the new cluster + controller.changeServerPool(cluster2.getId()); + assertEquals(controller.config().get(LoadBalancer.SERVER_POOL), cluster2); + assertEventuallyAddressesMatchCluster(cluster2); + + // And remove all children; expect all addresses to go away + cluster2.resize(0); + assertEventuallyAddressesMatchCluster(cluster2); + } + protected void assertEventuallyAddressesMatchCluster() { assertEventuallyAddressesMatchCluster(cluster); }