You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/03/18 23:12:50 UTC

[5/7] incubator-brooklyn git commit: rest state export uses same memento generation (from RebindSupport)

rest state export uses same memento generation (from RebindSupport)

fixes problem characterized by @grkvlt, where the REST memento generation did not correctly call in via the RebindSupport subsystem on BrooklynObjects; it does now, with test (which failed before the fix, in the manner observed in the wild with the PortForwardManager). methods renamed and deprecated to make the intended usage clearer. also better error reporting should PortForwardManager encounter similar problems in the future (which it shouldn't).


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

Branch: refs/heads/master
Commit: c7449ac00ecd607aa6a09f11c34ca70adb26b024
Parents: e7f64fb
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Mar 17 13:20:51 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Mar 18 22:08:20 2015 +0000

----------------------------------------------------------------------
 .../AbstractBrooklynObjectRebindSupport.java    |  2 +-
 .../entity/rebind/dto/MementosGenerators.java   | 55 ++++++++++++++++++--
 .../persister/BrooklynPersistenceUtils.java     |  4 +-
 .../location/access/PortForwardManagerImpl.java |  7 +--
 .../entity/rebind/RebindCatalogItemTest.java    |  4 +-
 ...talogWhenCatalogPersistenceDisabledTest.java |  8 +--
 .../entity/rebind/RebindTestFixture.java        | 10 +++-
 .../access/PortForwardManagerRebindTest.java    | 45 ++++++++++++++++
 8 files changed, 118 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
index 0d6e663..273d3ec 100644
--- a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
@@ -41,7 +41,7 @@ public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> imp
     @Override
     @SuppressWarnings("unchecked")
     public T getMemento() {
-        T memento = (T) MementosGenerators.newMemento(instance);
+        T memento = (T) MementosGenerators.newBasicMemento(instance);
         if (LOG.isTraceEnabled()) LOG.trace("Created memento: {}", memento.toVerboseString());
         return memento;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index a9d4b66..91d7736 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -37,7 +37,9 @@ import brooklyn.entity.Feed;
 import brooklyn.entity.Group;
 import brooklyn.entity.basic.EntityDynamicType;
 import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.rebind.AbstractBrooklynObjectRebindSupport;
 import brooklyn.entity.rebind.TreeUtils;
+import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.AttributeSensor.SensorPersistenceMode;
 import brooklyn.event.feed.AbstractFeed;
@@ -61,6 +63,7 @@ import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.flags.FlagUtils;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.base.Predicates;
 
@@ -68,10 +71,23 @@ public class MementosGenerators {
 
     private MementosGenerators() {}
     
+    /** @deprecated since 0.7.0 use {@link #newBasicMemento(BrooklynObject)} */
+    public static Memento newMemento(BrooklynObject instance) {
+        return newBasicMemento(instance);
+    }
+    
     /**
-     * Inspects a brooklyn object to create a corresponding memento.
+     * Inspects a brooklyn object to create a basic corresponding memento.
+     * <p>
+     * The memento is "basic" in the sense that it does not tie in to any entity-specific customization;
+     * the corresponding memento may subsequently be customized by the caller.
+     * <p>
+     * This method is intended for use by {@link AbstractBrooklynObjectRebindSupport#getMemento()}
+     * and callers wanting a memento for an object should use that, or the
+     * {@link BrooklynPersistenceUtils#newObjectMemento(BrooklynObject)} convenience.
      */
-    public static Memento newMemento(BrooklynObject instance) {
+    @Beta
+    public static Memento newBasicMemento(BrooklynObject instance) {
         if (instance instanceof Entity) {
             return newEntityMemento((Entity)instance);
         } else if (instance instanceof Location) {
@@ -127,13 +143,16 @@ public class MementosGenerators {
     
     /**
      * Inspects an entity to create a corresponding memento.
+     * <p>
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
      */
+    @Deprecated
     public static EntityMemento newEntityMemento(Entity entity) {
         return newEntityMementoBuilder(entity).build();
     }
 
     /**
-     * @deprecated since 0.7.0; use {@link #newMemento(BrooklynObject)} instead
+     * @deprecated since 0.7.0; use {@link #newBasicMemento(BrooklynObject)} instead
      */
     @Deprecated
     public static BasicEntityMemento.Builder newEntityMementoBuilder(Entity entityRaw) {
@@ -210,7 +229,11 @@ public class MementosGenerators {
 
         return builder;
     }
-    
+ 
+    /**
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
+     */
+    @Deprecated
     public static Function<Entity, EntityMemento> entityMementoFunction() {
         return new Function<Entity,EntityMemento>() {
             @Override
@@ -228,13 +251,16 @@ public class MementosGenerators {
      * the location reference is replaced by the location id.
      * TODO When we have a cleaner separation of constructor/config for entities and locations, then
      * we will remove this code!
+     * 
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
      */
+    @Deprecated
     public static LocationMemento newLocationMemento(Location location) {
         return newLocationMementoBuilder(location).build();
     }
     
     /**
-     * @deprecated since 0.7.0; use {@link #newMemento(BrooklynObject)} instead
+     * @deprecated since 0.7.0; use {@link #newBasicMemento(BrooklynObject)} instead
      */
     @Deprecated
     public static BasicLocationMemento.Builder newLocationMementoBuilder(Location location) {
@@ -267,6 +293,10 @@ public class MementosGenerators {
         return builder;
     }
     
+    /**
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
+     */
+    @Deprecated
     public static Function<Location, LocationMemento> locationMementoFunction() {
         return new Function<Location,LocationMemento>() {
             @Override
@@ -279,7 +309,10 @@ public class MementosGenerators {
     
     /**
      * Given a policy, extracts its state for serialization.
+     * 
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
      */
+    @Deprecated
     public static PolicyMemento newPolicyMemento(Policy policy) {
         BasicPolicyMemento.Builder builder = BasicPolicyMemento.builder();
         populateBrooklynObjectMementoBuilder(policy, builder);
@@ -305,6 +338,10 @@ public class MementosGenerators {
         return builder.build();
     }
     
+    /**
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
+     */
+    @Deprecated
     public static Function<Policy, PolicyMemento> policyMementoFunction() {
         return new Function<Policy,PolicyMemento>() {
             @Override
@@ -316,7 +353,9 @@ public class MementosGenerators {
 
     /**
      * Given an enricher, extracts its state for serialization.
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
      */
+    @Deprecated
     public static EnricherMemento newEnricherMemento(Enricher enricher) {
         BasicEnricherMemento.Builder builder = BasicEnricherMemento.builder();
         populateBrooklynObjectMementoBuilder(enricher, builder);
@@ -344,7 +383,9 @@ public class MementosGenerators {
 
     /**
      * Given a feed, extracts its state for serialization.
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
      */
+    @Deprecated
     public static FeedMemento newFeedMemento(Feed feed) {
         BasicFeedMemento.Builder builder = BasicFeedMemento.builder();
         populateBrooklynObjectMementoBuilder(feed, builder);
@@ -363,6 +404,10 @@ public class MementosGenerators {
         return builder.build();
     }
     
+    /**
+     * @deprecated since 0.7.0, see {@link #newBasicMemento(BrooklynObject)}
+     */
+    @Deprecated
     public static CatalogItemMemento newCatalogItemMemento(CatalogItem<?, ?> catalogItem) {
         if (catalogItem instanceof CatalogItemDo<?,?>) {
             catalogItem = ((CatalogItemDo<?,?>)catalogItem).getDto();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/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 e1ed10e..24a2d38 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.basic.BrooklynObject;
+import brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.catalog.CatalogItem;
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.config.BrooklynServerPaths;
@@ -34,7 +35,6 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.BrooklynObjectType;
 import brooklyn.entity.rebind.PersistenceExceptionHandler;
 import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl;
-import brooklyn.entity.rebind.dto.MementosGenerators;
 import brooklyn.entity.rebind.transformer.CompoundTransformer;
 import brooklyn.entity.rebind.transformer.CompoundTransformerLoader;
 import brooklyn.location.Location;
@@ -132,7 +132,7 @@ public class BrooklynPersistenceUtils {
     }
 
     public static Memento newObjectMemento(BrooklynObject instance) {
-        return MementosGenerators.newMemento(instance);
+        return ((BrooklynObjectInternal)instance).getRebindSupport().getMemento();
     }
     
     public static BrooklynMementoRawData newStateMemento(ManagementContext mgmt, MementoCopyMode source) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java b/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
index f392de0..6a290f7 100644
--- a/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
+++ b/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
@@ -42,6 +42,7 @@ import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -133,9 +134,9 @@ public class PortForwardManagerImpl extends AbstractLocation implements PortForw
             @Override
             protected void doReconstruct(RebindContext rebindContext, LocationMemento memento) {
                 super.doReconstruct(rebindContext, memento);
-                mappings.putAll((Map<String, PortMapping>) memento.getCustomField("mappings"));
-                portReserved.set((Integer)memento.getCustomField("portReserved"));
-                publicIpIdToHostname.putAll((Map<String, String>)memento.getCustomField("publicIpIdToHostname"));
+                mappings.putAll( Preconditions.checkNotNull((Map<String, PortMapping>) memento.getCustomField("mappings"), "mappings was not serialized correctly"));
+                portReserved.set( (Integer)memento.getCustomField("portReserved"));
+                publicIpIdToHostname.putAll( Preconditions.checkNotNull((Map<String, String>)memento.getCustomField("publicIpIdToHostname"), "publicIpIdToHostname was not serialized correctly") );
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
index 4454354..5e555c7 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
@@ -25,6 +25,8 @@ import static org.testng.Assert.fail;
 import io.brooklyn.camp.BasicCampPlatform;
 import io.brooklyn.camp.test.mock.web.MockWebPlatform;
 
+import java.io.File;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;
@@ -87,7 +89,7 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
     }
 
     @Override
-    protected LocalManagementContext createNewManagementContext() {
+    protected LocalManagementContext createNewManagementContext(File mementoDir) {
         BrooklynProperties properties = BrooklynProperties.Factory.newDefault();
         properties.put(BrooklynServerConfig.BROOKLYN_CATALOG_URL, "classpath://brooklyn/entity/rebind/rebind-catalog-item-test-catalog.xml");
         properties.put(BrooklynServerConfig.CATALOG_LOAD_MODE, CatalogLoadMode.LOAD_BROOKLYN_CATALOG_URL_IF_NO_PERSISTED_STATE);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/test/java/brooklyn/entity/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
index 8a64e6c..7c6393a 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
@@ -20,12 +20,12 @@ package brooklyn.entity.rebind;
 
 import static org.testng.Assert.assertEquals;
 
+import java.io.File;
+
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.Iterables;
-
 import brooklyn.camp.lite.CampPlatformWithJustBrooklynMgmt;
 import brooklyn.catalog.CatalogItem;
 import brooklyn.config.BrooklynProperties;
@@ -35,6 +35,8 @@ import brooklyn.internal.BrooklynFeatureEnablement;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.entity.TestEntity;
 
+import com.google.common.collect.Iterables;
+
 public class RebindCatalogWhenCatalogPersistenceDisabledTest extends RebindTestFixtureWithApp {
 
     private static final String TEST_CATALOG = "classpath://brooklyn/entity/rebind/rebind-catalog-item-test-catalog.xml";
@@ -69,7 +71,7 @@ public class RebindCatalogWhenCatalogPersistenceDisabledTest extends RebindTestF
     }
 
     @Override
-    protected LocalManagementContext createNewManagementContext() {
+    protected LocalManagementContext createNewManagementContext(File mementoDir) {
         BrooklynProperties properties = BrooklynProperties.Factory.newDefault();
         properties.put(BrooklynServerConfig.BROOKLYN_CATALOG_URL, TEST_CATALOG);
         return RebindTestUtils.managementContextBuilder(mementoDir, classLoader)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
index 8f1c1c6..0746d44 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindTestFixture.java
@@ -94,8 +94,14 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
                 .buildStarted();
     }
 
-    /** @return An unstarted management context */
+    /** As {@link #createNewManagementContext(File)} using the default memento dir */
     protected LocalManagementContext createNewManagementContext() {
+        return createNewManagementContext(mementoDir);
+    }
+    
+    /** @return An unstarted management context using the specified mementoDir (or default if null) */
+    protected LocalManagementContext createNewManagementContext(File mementoDir) {
+        if (mementoDir==null) mementoDir = this.mementoDir;
         return RebindTestUtils.managementContextBuilder(mementoDir, classLoader)
                 .forLive(useLiveManagementContext())
                 .emptyCatalog(useEmptyCatalog())
@@ -237,7 +243,7 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
         if (options.classLoader == null) options.classLoader(classLoader);
         if (options.mementoDir == null) options.mementoDir(mementoDir);
         if (options.origManagementContext == null) options.origManagementContext(origManagementContext);
-        if (options.newManagementContext == null) options.newManagementContext(createNewManagementContext());
+        if (options.newManagementContext == null) options.newManagementContext(createNewManagementContext(options.mementoDir));
         
         RebindTestUtils.waitForPersisted(origApp);
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c7449ac0/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java b/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
index 5ad0296..2d4b326 100644
--- a/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
+++ b/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
@@ -21,6 +21,8 @@ package brooklyn.location.access;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotEquals;
 
+import java.io.File;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
@@ -29,16 +31,24 @@ import org.testng.annotations.Test;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
+import brooklyn.entity.rebind.persister.FileBasedObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.location.Location;
 import brooklyn.location.LocationSpec;
 import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.management.ha.MementoCopyMode;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.test.entity.TestEntityImpl;
 import brooklyn.util.net.Networking;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.time.Time;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
@@ -86,6 +96,41 @@ public class PortForwardManagerRebindTest extends RebindTestFixtureWithApp {
     }
     
     @Test
+    public void testAssociationPreservedOnStateExport() throws Exception {
+        String publicIpId = "5.6.7.8";
+        String publicAddress = "5.6.7.8";
+
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
+        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+
+        origPortForwardManager.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), origSimulatedMachine, 80);
+
+        String label = origManagementContext.getManagementNodeId()+"-"+Time.makeDateSimpleStampString();
+        PersistenceObjectStore targetStore = BrooklynPersistenceUtils.newPersistenceObjectStore(origManagementContext, null, 
+            "tmp/web-persistence-"+label+"-"+Identifiers.makeRandomId(4));
+        File dir = ((FileBasedObjectStore)targetStore).getBaseDir();
+        // only register the parent dir because that will prevent leaks for the random ID
+        Os.deleteOnExitEmptyParentsUpTo(dir.getParentFile(), dir.getParentFile());
+        BrooklynPersistenceUtils.writeMemento(origManagementContext, targetStore, MementoCopyMode.LOCAL);            
+
+        RebindTestUtils.waitForPersisted(origApp);
+        log.info("Using manual export dir "+dir+" for rebind instead of "+mementoDir);
+        newApp = rebind(RebindOptions.create().mementoDir(dir));
+        
+        // After rebind, confirm that lookups still work
+        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
+        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
+        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+        
+        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+        
+        // delete the dir here, to be more likely not to leak it on failure
+        newManagementContext.getRebindManager().stop();
+        Os.deleteRecursively(dir);
+    }
+    
+    @Test
     public void testAssociationPreservedOnRebindLegacy() throws Exception {
         String publicIpId = "5.6.7.8";
         String publicAddress = "5.6.7.8";