brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [1/5] incubator-brooklyn git commit: better handling for the case where an already-managed active item is rebinded active
Date Tue, 18 Nov 2014 17:53:15 GMT
Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 0f2f63279 -> 4ced56e12


better handling for the case where an already-managed active item is rebinded active

do not clear the old location's record, and better logging


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2fdc3f9f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2fdc3f9f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2fdc3f9f

Branch: refs/heads/master
Commit: 2fdc3f9fe8f4984fb58ad1d7f43de18bab655691
Parents: cb043e2
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Tue Nov 18 11:21:59 2014 +0000
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Tue Nov 18 11:25:02 2014 +0000

----------------------------------------------------------------------
 .../entity/rebind/RebindManagerImpl.java        | 33 ++++++--
 .../BrooklynMementoPersisterToObjectStore.java  |  2 +-
 .../persister/BrooklynPersistenceUtils.java     |  6 +-
 .../persister/RetryingMementoSerializer.java    | 13 ++-
 .../location/basic/SshMachineLocation.java      |  2 +-
 .../internal/LocalLocationManager.java          |  7 +-
 .../ha/HighAvailabilityManagerInMemoryTest.java | 86 ++++++++++++++++++++
 .../ha/HighAvailabilityManagerTestFixture.java  |  2 +-
 .../location/jclouds/JcloudsLocation.java       |  2 +-
 9 files changed, 135 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
index ed59bcc..1319caa 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
@@ -66,6 +66,7 @@ import brooklyn.location.Location;
 import brooklyn.location.basic.AbstractLocation;
 import brooklyn.location.basic.LocationInternal;
 import brooklyn.management.ExecutionContext;
+import brooklyn.management.ManagementContext;
 import brooklyn.management.Task;
 import brooklyn.management.classloading.BrooklynClassLoadingContext;
 import brooklyn.management.ha.HighAvailabilityManagerImpl;
@@ -114,6 +115,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -601,13 +603,25 @@ public class RebindManagerImpl implements RebindManager {
             BrooklynMementoRawData mementoRawData = persistenceStoreAccess.loadMementoRawData(exceptionHandler);
             BrooklynMementoManifest mementoManifest = persistenceStoreAccess.loadMementoManifest(mementoRawData,
exceptionHandler);
 
+            boolean overwritingMaster = false;
             boolean isEmpty = mementoManifest.isEmpty();
             if (mode!=ManagementNodeState.HOT_STANDBY && mode!=ManagementNodeState.HOT_BACKUP)
{
                 if (!isEmpty) { 
-                    LOG.info("Rebinding from "+getPersister().getBackingStoreDescription()+"...");
+                    LOG.info("Rebinding from "+getPersister().getBackingStoreDescription()+"
for "+Strings.toLowerCase(Strings.toString(mode))+" "+managementContext.getManagementNodeId()+"...");
                 } else {
                     LOG.info("Rebind check: no existing state; will persist new items to
"+getPersister().getBackingStoreDescription());
                 }
+                
+                if (!managementContext.getEntityManager().getEntities().isEmpty() || !managementContext.getLocationManager().getLocations().isEmpty())
{
+                    // this is discouraged if we were already master
+                    Entity anEntity = Iterables.getFirst(managementContext.getEntityManager().getEntities(),
null);
+                    if (anEntity!=null && !((EntityInternal)anEntity).getManagementSupport().isReadOnly())
{
+                        overwritingMaster = true;
+                        LOG.warn("Rebind requested for "+mode+" node "+managementContext.getManagementNodeId()+"
"
+                            + "when it already has active state; discouraged, "
+                            + "will likely overwrite: "+managementContext.getEntityManager().getEntities()+"
and "+managementContext.getLocationManager().getLocations()+" and more");
+                    }
+                }
             }
 
             //
@@ -928,7 +942,7 @@ public class RebindManagerImpl implements RebindManager {
             Set<String> oldLocations = Sets.newLinkedHashSet(locationManager.getLocationIds());
             for (Location location: rebindContext.getLocations()) {
                 ManagementTransitionMode oldMode = locationManager.getLastManagementTransitionMode(location.getId());
-                locationManager.setManagementTransitionMode(location, computeMode(location,
oldMode, rebindContext.isReadOnly(location)) );
+                locationManager.setManagementTransitionMode(location, computeMode(managementContext,
location, oldMode, rebindContext.isReadOnly(location)) );
                 if (oldMode!=null)
                     oldLocations.remove(location.getId());
             }
@@ -943,6 +957,8 @@ public class RebindManagerImpl implements RebindManager {
                 }
             }
             // destroy old
+            if (!oldLocations.isEmpty()) BrooklynLogging.log(LOG, overwritingMaster ? BrooklynLogging.LoggingLevel.WARN
: BrooklynLogging.LoggingLevel.DEBUG, 
+                "Destroying unused locations on rebind: "+oldLocations);
             for (String oldLocationId: oldLocations) {
                locationManager.unmanage(locationManager.getLocation(oldLocationId), ManagementTransitionMode.REBINDING_DESTROYED);

             }
@@ -953,7 +969,7 @@ public class RebindManagerImpl implements RebindManager {
             Set<String> oldEntities = Sets.newLinkedHashSet(entityManager.getEntityIds());
             for (Entity entity: rebindContext.getEntities()) {
                 ManagementTransitionMode oldMode = entityManager.getLastManagementTransitionMode(entity.getId());
-                entityManager.setManagementTransitionMode(entity, computeMode(entity, oldMode,
rebindContext.isReadOnly(entity)) );
+                entityManager.setManagementTransitionMode(entity, computeMode(managementContext,entity,
oldMode, rebindContext.isReadOnly(entity)) );
                 if (oldMode!=null)
                     oldEntities.remove(entity.getId());
             }
@@ -973,6 +989,8 @@ public class RebindManagerImpl implements RebindManager {
                 }
             }
             // destroy old
+            if (!oldLocations.isEmpty()) BrooklynLogging.log(LOG, overwritingMaster ? BrooklynLogging.LoggingLevel.WARN
: BrooklynLogging.LoggingLevel.DEBUG, 
+                "Destroying unused entities on rebind: "+oldEntities);
             for (String oldEntityId: oldEntities) {
                entityManager.unmanage(entityManager.getEntity(oldEntityId), ManagementTransitionMode.REBINDING_DESTROYED);

             }
@@ -1105,11 +1123,11 @@ public class RebindManagerImpl implements RebindManager {
         }
     }
 
-    static ManagementTransitionMode computeMode(BrooklynObject item, ManagementTransitionMode
oldMode, boolean isNowReadOnly) {
-        return computeMode(item, oldMode==null ? null : oldMode.wasReadOnly(), isNowReadOnly);
+    static ManagementTransitionMode computeMode(ManagementContext mgmt, BrooklynObject item,
ManagementTransitionMode oldMode, boolean isNowReadOnly) {
+        return computeMode(mgmt, item, oldMode==null ? null : oldMode.wasReadOnly(), isNowReadOnly);
     }
 
-    static ManagementTransitionMode computeMode(BrooklynObject item, Boolean wasReadOnly,
boolean isNowReadOnly) {
+    static ManagementTransitionMode computeMode(ManagementContext mgmt, BrooklynObject item,
Boolean wasReadOnly, boolean isNowReadOnly) {
         if (wasReadOnly==null) {
             // not known
             if (Boolean.TRUE.equals(isNowReadOnly)) return ManagementTransitionMode.REBINDING_READONLY;
@@ -1122,7 +1140,8 @@ public class RebindManagerImpl implements RebindManager {
             else if (isNowReadOnly)
                 return ManagementTransitionMode.REBINDING_NO_LONGER_PRIMARY;
             else {
-                LOG.warn("Transitioning to master, though never stopped being a master -
" + item);
+                // for the most part we handle this correctly, although there may be leaks;
see HighAvailabilityManagerInMemoryTest.testLocationsStillManagedCorrectlyAfterDoublePromotion
+                LOG.warn("Node "+(mgmt!=null ? mgmt.getManagementNodeId() : null)+" rebinding
as master when already master (discouraged, may have stale references); for: "+item);
                 return ManagementTransitionMode.REBINDING_BECOMING_PRIMARY;
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
index 115fecc..9b0f462 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
@@ -557,7 +557,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
 
         Stopwatch stopwatch = deltaImpl(delta, exceptionHandler);
         
-        if (LOG.isDebugEnabled()) LOG.debug("Checkpointed delta of memento in {}: "
+        if (LOG.isDebugEnabled()) LOG.debug("7 in {}: "
                 + "updated {} entities, {} locations, {} policies, {} enrichers, {} catalog
items; "
                 + "removed {} entities, {} locations, {} policies, {} enrichers, {} catalog
items",
                     new Object[] {Time.makeTimeStringRounded(stopwatch),

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
index 9d2721d..e1ed10e 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
@@ -238,7 +238,11 @@ public class BrooklynPersistenceUtils {
                 log.debug("Backing up persisted state on "+mode+", to "+destinationObjectStore.getSummaryName());
                 BrooklynPersistenceUtils.writeMemento(managementContext, memento, destinationObjectStore);
                 BrooklynPersistenceUtils.writeManagerMemento(managementContext, planeState,
destinationObjectStore);
-                log.info("Back-up of persisted state created on "+mode+", in "+destinationObjectStore.getSummaryName());
+                if (!memento.isEmpty()) {
+                    log.info("Back-up of persisted state created on "+mode+", in "+destinationObjectStore.getSummaryName());
+                } else {
+                    log.debug("Back-up of (empty) persisted state created on "+mode+", in
"+destinationObjectStore.getSummaryName());
+                }
                 
             } catch (Exception e) {
                 Exceptions.propagateIfFatal(e);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/entity/rebind/persister/RetryingMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/RetryingMementoSerializer.java
b/core/src/main/java/brooklyn/entity/rebind/persister/RetryingMementoSerializer.java
index f94fa45..9bcf81c 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/RetryingMementoSerializer.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/RetryingMementoSerializer.java
@@ -45,7 +45,10 @@ public class RetryingMementoSerializer<T> implements MementoSerializer<T>
{
         do {
             attempt++;
             try {
-                return delegate.toString(memento);
+                String result = delegate.toString(memento);
+                if (attempt>1) 
+                    LOG.info("Success following previous serialization error");
+                return result;
             } catch (RuntimeException e) {
                 LOG.warn("Error serializing memento (attempt "+attempt+" of "+maxAttempts+")
for "+memento+
                         "; expected sometimes if attribute value modified", e);
@@ -66,10 +69,14 @@ public class RetryingMementoSerializer<T> implements MementoSerializer<T>
{
         do {
             attempt++;
             try {
-                return delegate.fromString(string);
+                T result = delegate.fromString(string);
+                if (attempt>1)
+                    LOG.info("Success following previous deserialization error, got: "+result);
+                return result;
             } catch (RuntimeException e) {
                 // trying multiple times only makes sense for a few errors (namely ConcModExceptions);
perhaps deprecate that strategy?
-                LOG.warn("Error deserializing memento (attempt "+attempt+" of "+maxAttempts+")",
e);
+                LOG.warn("Error deserializing memento (attempt "+attempt+" of "+maxAttempts+"):
"+e, e);
+                if (attempt==1) LOG.debug("Memento which was not deserialized is:\n"+string);
                 lastException = e;
             }
         } while (attempt < maxAttempts);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java b/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
index 57dd660..03e53c6 100644
--- a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
@@ -798,7 +798,7 @@ public class SshMachineLocation extends AbstractLocation implements MachineLocat
 
     @Override
     public String toString() {
-        return "SshMachineLocation["+getDisplayName()+":"+address+"]";
+        return "SshMachineLocation["+getDisplayName()+":"+address+"@"+getId()+"]";
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
index f81cb98..8a95808 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
@@ -268,9 +268,8 @@ public class LocalLocationManager implements LocationManagerInternal {
         if (shouldSkipUnmanagement(loc)) return;
 
         if (hasBeenReplaced) {
-            // we are unmanaging an old instance after having replaced it
-            unmanageNonRecursiveClearItsFields(loc, mode);
-            
+            // we are unmanaging an old instance after having replaced it; 
+            // don't unmanage or even clear its fields, because there might be references
to it
             if (mode==ManagementTransitionMode.REBINDING_NO_LONGER_PRIMARY) {
                 // when migrating away, these all need to be called
                 managementContext.getRebindManager().getChangeListener().onUnmanaged(loc);
@@ -280,6 +279,8 @@ public class LocalLocationManager implements LocationManagerInternal {
                 if (!mode.wasReadOnly())
                     log.warn("Should not be unmanaging "+loc+" in mode "+mode+"; ignoring");
             }
+            // do not remove from maps below, bail out now
+            return;
 
         } else if (mode==ManagementTransitionMode.REBINDING_DESTROYED || mode==ManagementTransitionMode.REBINDING_NO_LONGER_PRIMARY)
{
             // we are unmanaging an instance whose primary management is elsewhere (either
we were secondary, or we are being demoted)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
index dfabd0b..7c9f213 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
@@ -18,14 +18,33 @@
  */
 package brooklyn.management.ha;
 
+import java.util.Collection;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.location.Location;
+import brooklyn.location.NoMachinesAvailableException;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.collections.MutableList;
+
+import com.google.common.collect.Iterables;
 
 @Test
 public class HighAvailabilityManagerInMemoryTest extends HighAvailabilityManagerTestFixture
{
 
+    private static final Logger log = LoggerFactory.getLogger(HighAvailabilityManagerInMemoryTest.class);
+    
     protected PersistenceObjectStore newPersistenceObjectStore() {
         return new InMemoryObjectStore();
     }
@@ -34,4 +53,71 @@ public class HighAvailabilityManagerInMemoryTest extends HighAvailabilityManager
         super.testGetManagementPlaneStatus();
     }
 
+    // extra test that promoteToMaster doesn't interfere with what is managed
+    public void testLocationsStillManagedCorrectlyAfterDoublePromotion() throws NoMachinesAvailableException
{
+        HighAvailabilityManagerImpl ha = (HighAvailabilityManagerImpl) managementContext.getHighAvailabilityManager();
+        ha.start(HighAvailabilityMode.MASTER);
+        
+        TestApplication app = TestApplication.Factory.newManagedInstanceForTests(managementContext);
+        
+        LocalhostMachineProvisioningLocation l = app.newLocalhostProvisioningLocation();
+        l.setConfig(TestEntity.CONF_NAME, "sample1");
+        Assert.assertEquals(l.getConfig(TestEntity.CONF_NAME), "sample1");
+        
+        SshMachineLocation l2 = l.obtain();
+        Assert.assertEquals(l2.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(l2.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(l2.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+
+        TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(l).location(l2));
+        log.info("Entities managed are: "+managementContext.getEntityManager().getEntities());
+        Collection<Location> le = entity.getLocations();
+        log.info("Locs at entity are: "+le);
+        Collection<Location> lm = managementContext.getLocationManager().getLocations();
+        log.info("Locs managed are: "+lm);
+        log.info("            objs: "+identities(lm));
+        
+        managementContext.getRebindManager().forcePersistNow(true, null);
+        log.info("DODGY extra promoteToMaster");
+        ha.promoteToMaster();
+        
+        log.info("Entities managed are: "+managementContext.getEntityManager().getEntities());
+        Collection<Location> lle = entity.getLocations();
+        log.info("Locs at entity(old) are: "+lle);
+        log.info("                   objs: "+identities(lle));
+        
+        // assert what's in the location manager is accurate
+        Collection<Location> llmm = managementContext.getLocationManager().getLocations();
+        log.info("Locs managed are: "+llmm);
+        log.info("            objs: "+identities(llmm));
+        Assert.assertEquals(llmm, lm);
+        SshMachineLocation ll2a = Iterables.getOnlyElement(Iterables.filter(llmm, SshMachineLocation.class));
+        Assert.assertEquals(ll2a.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(ll2a.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(ll2a.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+        
+        // and what's in the location manager is accurate
+        Entity ee = (Entity)managementContext.lookup(entity.getId());
+        Collection<Location> llee = ee.getLocations();
+        log.info("Locs at entity(lookup) are: "+llee);
+        log.info("                      objs: "+identities(llee));
+        SshMachineLocation ll2b = Iterables.getOnlyElement(Iterables.filter(llee, SshMachineLocation.class));
+        Assert.assertEquals(ll2b.getConfig(TestEntity.CONF_NAME), "sample1");
+        Assert.assertNotNull(ll2b.getParent(), "Parent not set after dodgy promoteToMaster");
+        Assert.assertEquals(ll2b.getParent().getConfig(TestEntity.CONF_NAME), "sample1");
+        
+    }
+
+    @Test(groups="Integration", invocationCount=50)
+    public void testLocationsStillManagedCorrectlyAfterDoublePromotionManyTimes() throws
NoMachinesAvailableException {
+        testLocationsStillManagedCorrectlyAfterDoublePromotion();
+    }
+    
+    private List<String> identities(Collection<?> objs) {
+        List<String> result = MutableList.of();
+        for (Object obj: objs)
+            result.add(Integer.toHexString(System.identityHashCode(obj)));
+        return result;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerTestFixture.java
b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerTestFixture.java
index 449b2d9..c9026e8 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerTestFixture.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerTestFixture.java
@@ -58,7 +58,7 @@ public abstract class HighAvailabilityManagerTestFixture {
     private static final Logger log = LoggerFactory.getLogger(HighAvailabilityManagerTestFixture.class);
     
     private ManagementPlaneSyncRecordPersister persister;
-    private ManagementContextInternal managementContext;
+    protected ManagementContextInternal managementContext;
     private String ownNodeId;
     private HighAvailabilityManagerImpl manager;
     private Ticker ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2fdc3f9f/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index c58d9be..26dc4ef 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -269,7 +269,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation
im
         if (configDescription!=null && configDescription.startsWith(getClass().getSimpleName()))
             return configDescription;
         return getClass().getSimpleName()+"["+getDisplayName()+":"+(identity != null ? identity
: null)+
-                (configDescription!=null ? "/"+configDescription : "") + "]";
+                (configDescription!=null ? "/"+configDescription : "") + "@" + getId() +
"]";
     }
 
     @Override


Mime
View raw message