Skip to content
Permalink
Browse files
clean up how start(Location) works, for Dynamic{Cluster,Fabric}
  • Loading branch information
ahgittin committed Jan 19, 2016
1 parent 1c7ab43 commit e3da35dcf9720c6627756f2d8c85431f7f7743ee
Showing 4 changed files with 39 additions and 38 deletions.
@@ -874,15 +874,18 @@ public Collection<Location> getLocations() {

@Override
public void addLocations(Collection<? extends Location> newLocations) {
if (newLocations==null || newLocations.isEmpty()) {
return;
}
synchronized (locations) {
List<Location> oldLocations = locations.get();
Set<Location> truelyNewLocations = Sets.newLinkedHashSet(newLocations);
truelyNewLocations.removeAll(oldLocations);
if (truelyNewLocations.size() > 0) {
locations.set(ImmutableList.<Location>builder().addAll(oldLocations).addAll(truelyNewLocations).build());
Set<Location> trulyNewLocations = Sets.newLinkedHashSet(newLocations);
trulyNewLocations.removeAll(oldLocations);
if (trulyNewLocations.size() > 0) {
locations.set(ImmutableList.<Location>builder().addAll(oldLocations).addAll(trulyNewLocations).build());
}

for (Location loc : truelyNewLocations) {
for (Location loc : trulyNewLocations) {
sensors().emit(AbstractEntity.LOCATION_ADDED, loc);
}
}
@@ -21,6 +21,8 @@
import java.util.Collection;
import java.util.Map;

import javax.annotation.Nullable;

import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
@@ -48,7 +50,7 @@
@Beta
public interface EntityInternal extends BrooklynObjectInternal, EntityLocal, Rebindable {

void addLocations(Collection<? extends Location> locations);
void addLocations(@Nullable Collection<? extends Location> locations);

void removeLocations(Collection<? extends Location> locations);

@@ -21,6 +21,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -311,9 +312,10 @@ public void setFactory(EntityFactory<?> factory) {
setConfigEvenIfOwned(FACTORY, factory);
}

private Location getLocation() {
private Location getLocation(boolean required) {
Collection<? extends Location> ll = Locations.getLocationsCheckingAncestors(getLocations(), this);
try {
if (!required && ll.isEmpty()) return null;
return Iterables.getOnlyElement(ll);
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
@@ -360,18 +362,17 @@ protected int getInitialQuorumSize() {

@Override
public void start(Collection<? extends Location> locsO) {
if (locsO!=null) {
checkArgument(locsO.size() <= 1, "Wrong number of locations supplied to start %s: %s", this, locsO);
addLocations(locsO);
}
Location loc = getLocation();
addLocations(locsO);
Location loc = getLocation(false);

EntitySpec<?> spec = getConfig(MEMBER_SPEC);
if (spec!=null) {
setDefaultDisplayName("Cluster of "+JavaClassNames.simpleClassName(spec.getType()) +" ("+loc+")");
setDefaultDisplayName("Cluster of "+JavaClassNames.simpleClassName(spec.getType()) +
(loc!=null ? " ("+loc+")" : ""));
}

if (isAvailabilityZoneEnabled()) {
if (loc==null) throw new IllegalStateException("When using availability zones, a location must be specified on the cluster");
sensors().set(SUB_LOCATIONS, findSubLocations(loc));
}

@@ -574,7 +575,7 @@ public String replaceMember(String memberId) {
Location memberLoc = null;
if (isAvailabilityZoneEnabled()) {
// this member's location could be a machine provisioned by a sub-location, or the actual sub-location
List<Location> subLocations = findSubLocations(getLocation());
List<Location> subLocations = findSubLocations(getLocation(true));
Collection<Location> actualMemberLocs = member.getLocations();
boolean foundMatch = false;
for (Iterator<Location> iter = actualMemberLocs.iterator(); !foundMatch && iter.hasNext();) {
@@ -605,7 +606,7 @@ public String replaceMember(String memberId) {
// Replacing member, so new member should be in the same location as that being replaced.
// Expect this to agree with `getMemberSpec().getLocations()` (if set). If not, then
// presumably there was a reason this specific member was started somewhere else!
memberLoc = getLocation();
memberLoc = getLocation(false);
}

Entity replacement = replaceMember(member, memberLoc, ImmutableMap.of());
@@ -616,7 +617,7 @@ public String replaceMember(String memberId) {
/**
* @throws StopFailedRuntimeException If stop failed, after successfully starting replacement
*/
protected Entity replaceMember(Entity member, Location memberLoc, Map<?, ?> extraFlags) {
protected Entity replaceMember(Entity member, @Nullable Location memberLoc, Map<?, ?> extraFlags) {
synchronized (mutex) {
ReferenceWithError<Optional<Entity>> added = addInSingleLocation(memberLoc, extraFlags);

@@ -653,7 +654,7 @@ protected Multimap<Location, Entity> getMembersByLocation() {
protected List<Location> getNonFailedSubLocations() {
List<Location> result = Lists.newArrayList();
Set<Location> failed = Sets.newLinkedHashSet();
List<Location> subLocations = findSubLocations(getLocation());
List<Location> subLocations = findSubLocations(getLocation(true));
Set<Location> oldFailedSubLocations = getAttribute(FAILED_SUB_LOCATIONS);
if (oldFailedSubLocations == null)
oldFailedSubLocations = ImmutableSet.<Location> of();
@@ -722,7 +723,7 @@ protected Collection<Entity> grow(int delta) {
+ ", when expected delta " + delta + " in " + this);
}
} else {
chosenLocations = Collections.nCopies(delta, getLocation());
chosenLocations = Collections.nCopies(delta, getLocation(false));
}

// create and start the entities.
@@ -759,8 +760,8 @@ protected Collection<Entity> shrink(int delta) {
}
}

protected ReferenceWithError<Optional<Entity>> addInSingleLocation(Location location, Map<?,?> flags) {
ReferenceWithError<Collection<Entity>> added = addInEachLocation(ImmutableList.of(location), flags);
protected ReferenceWithError<Optional<Entity>> addInSingleLocation(@Nullable Location location, Map<?,?> flags) {
ReferenceWithError<Collection<Entity>> added = addInEachLocation(Arrays.asList(location), flags);

Optional<Entity> result = Iterables.isEmpty(added.getWithoutError()) ? Optional.<Entity>absent() : Optional.of(Iterables.getOnlyElement(added.get()));
if (!added.hasError()) {
@@ -885,7 +886,7 @@ protected Map<?,?> getCustomChildFlags() {
}

@Override
public Entity addNode(Location loc, Map<?, ?> extraFlags) {
public Entity addNode(@Nullable Location loc, Map<?, ?> extraFlags) {
// In case subclasses are foolish and do not call super.init() when overriding.
initialiseMemberId();
Map<?, ?> createFlags = MutableMap.builder()
@@ -917,7 +918,9 @@ protected Entity createNode(@Nullable Location loc, Map<?,?> flags) {
if (memberSpec == null) memberSpec = getMemberSpec();

if (memberSpec != null) {
return addChild(EntitySpec.create(memberSpec).configure(flags).location(loc));
EntitySpec<?> specConfigured = EntitySpec.create(memberSpec).configure(flags);
if (loc!=null) specConfigured.location(loc);
return addChild(specConfigured);
}

EntityFactory<?> factory = getFactory();
@@ -18,13 +18,11 @@
*/
package org.apache.brooklyn.entity.group;

import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.truth;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -112,16 +110,11 @@ public void setFactory(EntityFactory<?> factory) {

@Override
public void start(Collection<? extends Location> locsO) {
if (locsO!=null) {
addLocations(locsO);
}
Collection<Location> locs = Collections.unmodifiableCollection(Locations.getLocationsCheckingAncestors(getLocations(), this));

List<Location> newLocations = MutableList.copyOf(locsO);
if (newLocations.isEmpty()) newLocations.addAll(locs);
addLocations(locsO);
List<Location> locationsToStart = MutableList.copyOf(Locations.getLocationsCheckingAncestors(locsO, this));

Preconditions.checkNotNull(newLocations, "locations must be supplied");
Preconditions.checkArgument(newLocations.size() >= 1, "One or more locations must be supplied");
Preconditions.checkNotNull(locationsToStart, "locations must be supplied");
Preconditions.checkArgument(locationsToStart.size() >= 1, "One or more locations must be supplied");

int locIndex = 0;

@@ -137,8 +130,8 @@ public void start(Collection<? extends Location> locsO) {
Location it = null;
if (child.getLocations().isEmpty())
// give him any of these locations if he has none, allowing round robin here
if (!newLocations.isEmpty()) {
it = newLocations.get(locIndex++ % newLocations.size());
if (!locationsToStart.isEmpty()) {
it = locationsToStart.get(locIndex++ % locationsToStart.size());
((EntityInternal)child).addLocations(Arrays.asList(it));
}

@@ -148,12 +141,12 @@ public void start(Collection<? extends Location> locsO) {
}
}
// remove all the locations we applied to existing nodes
while (locIndex-->0 && !newLocations.isEmpty())
newLocations.remove(0);
while (locIndex-->0 && !locationsToStart.isEmpty())
locationsToStart.remove(0);

// finally (and usually) we create new entities for locations passed in
// (unless they were consumed by pre-existing children which didn't have locations)
for (Location it : newLocations) {
for (Location it : locationsToStart) {
Entity e = addCluster(it);

((EntityInternal)e).addLocations(Arrays.asList(it));

0 comments on commit e3da35d

Please sign in to comment.