brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [54/72] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - jclouds last few package prefixes needed, and tidy in core and elsewhere related (or observed in the process)
Date Wed, 19 Aug 2015 11:10:12 GMT
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
new file mode 100644
index 0000000..fb68c77
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -0,0 +1,362 @@
+/*
+ * 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.location.winrm;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+import com.google.common.reflect.TypeToken;
+
+import org.apache.brooklyn.location.access.PortForwardManager;
+import org.apache.brooklyn.location.core.AbstractLocation;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+
+import io.cloudsoft.winrm4j.winrm.WinRmTool;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
+
+    // FIXME Respect `port` config when using {@link WinRmTool}
+    public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
+            "port",
+            "WinRM port to use when connecting to the remote machine",
+            5985);
+    
+    // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
+    public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
+            "Username to use when connecting to the remote machine");
+
+    // TODO merge with {link SshTool#PROP_PASSWORD}
+    public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
+            "Password to use when connecting to the remote machine");
+
+    public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
+            "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
+
+     public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
+            InetAddress.class,
+            "address",
+            "Address of the remote machine");
+
+    public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
+            "windows.exec.attempts",
+            "Number of attempts to execute a remote command",
+            1);
+    
+    // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
+    public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
+            "execTries", 
+            "Max number of times to attempt WinRM operations", 
+            10);
+
+    public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
+            new TypeToken<Iterable<String>>() {},
+            "privateAddresses",
+            "Private addresses of this machine, e.g. those within the private network", 
+            null);
+
+    public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
+            new TypeToken<Map<Integer, String>>() {},
+            "tcpPortMappings",
+            "NAT'ed ports, giving the mapping from private TCP port to a public host:port", 
+            null);
+
+    @Override
+    public InetAddress getAddress() {
+        return getConfig(ADDRESS);
+    }
+
+    @Override
+    public OsDetails getOsDetails() {
+        return null;
+    }
+
+    @Override
+    public MachineDetails getMachineDetails() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getHostname() {
+        InetAddress address = getAddress();
+        return (address != null) ? address.getHostAddress() : null;
+    }
+
+    @Nullable
+    protected String getHostAndPort() {
+        String host = getHostname();
+        return (host == null) ? null : host + ":" + config().get(WINRM_PORT);
+    }
+
+    @Override
+    public Set<String> getPublicAddresses() {
+        InetAddress address = getAddress();
+        return (address == null) ? ImmutableSet.<String>of() : ImmutableSet.of(address.getHostAddress());
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
+        return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
+    }
+
+    public WinRmToolResponse executeScript(String script) {
+        return executeScript(ImmutableList.of(script));
+    }
+
+    public WinRmToolResponse executeScript(List<String> script) {
+        int execTries = getRequiredConfig(EXEC_TRIES);
+        Collection<Throwable> exceptions = Lists.newArrayList();
+        for (int i = 0; i < execTries; i++) {
+            try {
+                return executeScriptNoRetry(script);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                if (i == (execTries+1)) {
+                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+                } else if (i == 0) {
+                    LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+                } else {
+                    LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+                }
+                exceptions.add(e);
+            }
+        }
+        throw Exceptions.propagate("failed to execute shell script", exceptions);
+    }
+
+    protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+        WinRmToolResponse response = winRmTool.executeScript(script);
+        return response;
+    }
+
+    public WinRmToolResponse executePsScript(String psScript) {
+        return executePsScript(ImmutableList.of(psScript));
+    }
+
+    public WinRmToolResponse executePsScript(List<String> psScript) {
+        int execTries = getRequiredConfig(EXEC_TRIES);
+        Collection<Throwable> exceptions = Lists.newArrayList();
+        for (int i = 0; i < execTries; i++) {
+            try {
+                return executePsScriptNoRetry(psScript);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                if (i == (execTries+1)) {
+                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+                } else if (i == 0) {
+                    LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+                    Time.sleep(Duration.FIVE_SECONDS);
+                } else {
+                    LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+                    Time.sleep(Duration.FIVE_SECONDS);
+                }
+                exceptions.add(e);
+            }
+        }
+        throw Exceptions.propagate("failed to execute powershell script", exceptions);
+    }
+
+    public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+        WinRmToolResponse response = winRmTool.executePs(psScript);
+        return response;
+    }
+
+    public int copyTo(File source, String destination) {
+        FileInputStream sourceStream = null;
+        try {
+            sourceStream = new FileInputStream(source);
+            return copyTo(sourceStream, destination);
+        } catch (FileNotFoundException e) {
+            throw Exceptions.propagate(e);
+        } finally {
+            if (sourceStream != null) {
+                Streams.closeQuietly(sourceStream);
+            }
+        }
+    }
+
+    public int copyTo(InputStream source, String destination) {
+        executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
+        try {
+            int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
+            byte[] inputData = new byte[chunkSize];
+            int bytesRead;
+            int expectedFileSize = 0;
+            while ((bytesRead = source.read(inputData)) > 0) {
+                byte[] chunk;
+                if (bytesRead == chunkSize) {
+                    chunk = inputData;
+                } else {
+                    chunk = Arrays.copyOf(inputData, bytesRead);
+                }
+                executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
+                        expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
+                        " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
+                expectedFileSize += bytesRead;
+            }
+
+            return 0;
+        } catch (java.io.IOException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    @Override
+    public void init() {
+        super.init();
+
+        // Register any pre-existing port-mappings with the PortForwardManager
+        Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
+        if (tcpPortMappings != null) {
+            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+            for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
+                int targetPort = entry.getKey();
+                HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
+                if (!publicEndpoint.hasPort()) {
+                    throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
+                }
+                pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
+            }
+        }
+    }
+    public String getUser() {
+        return config().get(USER);
+    }
+
+    private String getPassword() {
+        return config().get(PASSWORD);
+    }
+
+    private <T> T getRequiredConfig(ConfigKey<T> key) {
+        return checkNotNull(getConfig(key), "key %s must be set", key);
+    }
+    
+    public static String getDefaultUserMetadataString() {
+        // Using an encoded command obviates the need to escape
+        String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
+                // Allow TS connections
+                "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices -Authentication PacketPrivacy",
+                "$RDP.SetAllowTSConnections(1,1)",
+                "Set-ExecutionPolicy Unrestricted -Force",
+                // Set unlimited values for remote execution limits
+                "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
+                "New-ItemProperty \"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name \"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
+                // The following allows scripts to re-authenticate with local credential - this is required
+                // as certain operations cannot be performed with remote credentials
+                "$allowed = @('WSMAN/*')",
+                "$key = 'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
+                "if (!(Test-Path $key)) {",
+                "    md $key",
+                "}",
+                "New-ItemProperty -Path $key -Name AllowFreshCredentials -Value 1 -PropertyType Dword -Force",
+                "New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
+                "$credKey = Join-Path $key 'AllowFreshCredentials'",
+                "if (!(Test-Path $credKey)) {",
+                "    md $credkey",
+                "}",
+                "$ntlmKey = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'",
+                "if (!(Test-Path $ntlmKey)) {",
+                "    md $ntlmKey",
+                "}",
+                "$i = 1",
+                "$allowed |% {",
+                "    # Script does not take into account existing entries in this key",
+                "    New-ItemProperty -Path $credKey -Name $i -Value $_ -PropertyType String -Force",
+                "    New-ItemProperty -Path $ntlmKey -Name $i -Value $_ -PropertyType String -Force",
+                "    $i++",
+                "}"
+        ));
+
+        String encoded = new String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
+        return "winrm quickconfig -q & " +
+                "winrm set winrm/config/service/auth @{Basic=\"true\"} & " +
+                "winrm set winrm/config/service/auth @{CredSSP=\"true\"} & " +
+                "winrm set winrm/config/client/auth @{CredSSP=\"true\"} & " +
+                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"} & " +
+                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"} & " +
+                "winrm set winrm/config/winrs @{MaxConcurrentUsers=\"100\"} & " +
+                "winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"0\"} & " +
+                "winrm set winrm/config/winrs @{MaxProcessesPerShell=\"0\"} & " +
+                "winrm set winrm/config/winrs @{MaxShellsPerUser=\"0\"} & " +
+                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any & " +
+                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any & " +
+                "powershell -EncodedCommand " + encoded;
+        /* TODO: Find out why scripts with new line characters aren't working on AWS. The following appears as if it *should*
+           work but doesn't - the script simply isn't run. By connecting to the machine via RDP, you can get the script
+           from 'http://169.254.169.254/latest/user-data', and running it at the command prompt works, but for some
+           reason the script isn't run when the VM is provisioned
+        */
+//        return Joiner.on("\r\n").join(ImmutableList.of(
+//                "winrm quickconfig -q",
+//                "winrm set winrm/config/service/auth @{Basic=\"true\"}",
+//                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"}",
+//                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"}",
+//                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any",
+//                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any",
+//                // Using an encoded command necessitates the need to escape. The unencoded command is as follows:
+//                // $RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\CIMV2\TerminalServices -Authentication PacketPrivacy
+//                // $Result = $RDP.SetAllowTSConnections(1,1)
+//                "powershell -EncodedCommand JABSAEQAUAAgAD0AIABHAGUAdAAtAFcAbQBpAE8AYgBqAGUAYwB0ACAALQBDAGwAYQBzAHMAI" +
+//                        "ABXAGkAbgAzADIAXwBUAGUAcgBtAGkAbgBhAGwAUwBlAHIAdgBpAGMAZQBTAGUAdAB0AGkAbgBnACAALQBDAG8AbQBwA" +
+//                        "HUAdABlAHIATgBhAG0AZQAgACQAZQBuAHYAOgBjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQAgAC0ATgBhAG0AZQBzAHAAY" +
+//                        "QBjAGUAIAByAG8AbwB0AFwAQwBJAE0AVgAyAFwAVABlAHIAbQBpAG4AYQBsAFMAZQByAHYAaQBjAGUAcwAgAC0AQQB1A" +
+//                        "HQAaABlAG4AdABpAGMAYQB0AGkAbwBuACAAUABhAGMAawBlAHQAUAByAGkAdgBhAGMAeQANAAoAJABSAGUAcwB1AGwAd" +
+//                        "AAgAD0AIAAkAFIARABQAC4AUwBlAHQAQQBsAGwAbwB3AFQAUwBDAG8AbgBuAGUAYwB0AGkAbwBuAHMAKAAxACwAMQApAA=="
+//        ));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
index 2277d49..b786a3e 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
@@ -26,9 +26,6 @@ import org.apache.brooklyn.api.internal.EntityLocal;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.effector.core.AddSensor;
-import org.apache.brooklyn.entity.java.JmxAttributeSensor;
-import org.apache.brooklyn.entity.software.ssh.SshCommandSensor;
-import org.apache.brooklyn.sensor.core.HttpRequestSensor;
 import org.apache.brooklyn.sensor.feed.http.HttpFeed;
 import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
 import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
index 58704bd..8102cb7 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.internal.BrooklynInitialization;
 import org.apache.brooklyn.entity.core.BrooklynConfigKeys;
-import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.core.Locations;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
index 880e56c..4730db7 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
@@ -34,9 +34,9 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.Locations;
-import org.apache.brooklyn.location.basic.Machines;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.core.Locations;
+import org.apache.brooklyn.location.core.Machines;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.sensor.feed.AbstractFeed;
 import org.apache.brooklyn.sensor.feed.AttributePollHandler;
 import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
index a2d5178..8f1885d 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.sensor.feed.ssh;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 
 public class SshPollValue {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
index c0ae91c..7c485b8 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
@@ -44,7 +44,7 @@ import org.apache.brooklyn.effector.core.EffectorTasks;
 import org.apache.brooklyn.entity.core.EntityInternal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
 import org.apache.brooklyn.sensor.core.Sensors;
 import org.apache.brooklyn.sensor.feed.AbstractFeed;
 import org.apache.brooklyn.sensor.feed.PollHandler;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
index 031198c..d568cc3 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
@@ -53,7 +53,7 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.util.EntityUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.http.HttpTool;
 import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveTasks.java
index ad79d9e..d73526e 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveTasks.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
index 74a95cb..b10d7ae 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/file/ArchiveUtils.java
@@ -30,7 +30,7 @@ import java.util.Set;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskFactory.java
index 5e180bd..707dd58 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskFactory.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.util.core.task.ssh;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 
 // cannot be (cleanly) instantiated due to nested generic self-referential type; however trivial subclasses do allow it 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskWrapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskWrapper.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskWrapper.java
index 6dcfc4d..c667d03 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskWrapper.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshFetchTaskWrapper.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.mgmt.TaskWrapper;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.Tasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskFactory.java
index 9a93778..7909df5 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskFactory.java
@@ -24,7 +24,7 @@ import java.io.Reader;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.stream.KnownSizeInputStream;
 import org.apache.brooklyn.util.stream.ReaderInputStream;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskStub.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskStub.java
index e838ad1..63ee96d 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskStub.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshPutTaskStub.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.util.core.task.ssh;
 
 import java.io.InputStream;
 
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
index 49cab10..53d5e71 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
@@ -35,9 +35,9 @@ import org.apache.brooklyn.core.config.ConfigUtils;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.AbstractLocation;
-import org.apache.brooklyn.location.basic.LocationInternal;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.core.AbstractLocation;
+import org.apache.brooklyn.location.core.internal.LocationInternal;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
index 62556f3..444f9f4 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.util.core.task.ssh.internal;
 
 import com.google.common.base.Preconditions;
 
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/PlainSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/PlainSshExecTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/PlainSshExecTaskFactory.java
index a6810a3..92def17 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/PlainSshExecTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/PlainSshExecTaskFactory.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.util.core.task.ssh.internal;
 
 import java.util.List;
 
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
index 0fd89cc..8042cc2 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskStub.ScriptReturnType;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
index 5dd1f1b..5514ccf 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
index 153dc59..6a98c4b 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
@@ -25,7 +25,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskStub;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
index 064c740..e96dce9 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java
@@ -27,7 +27,7 @@ import java.util.Map;
 
 import org.slf4j.Logger;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
index 2dd6fa9..ab87480 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
@@ -22,7 +22,7 @@ import java.io.File;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
index ec34011..ec64955 100644
--- a/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
+++ b/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
@@ -16,12 +16,12 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-org.apache.brooklyn.location.basic.DefinedLocationByIdResolver
-org.apache.brooklyn.location.basic.NamedLocationResolver
-org.apache.brooklyn.location.basic.CatalogLocationResolver
-org.apache.brooklyn.location.basic.LocalhostLocationResolver
-org.apache.brooklyn.location.basic.ByonLocationResolver
-org.apache.brooklyn.location.basic.SingleMachineLocationResolver
-org.apache.brooklyn.location.basic.HostLocationResolver
-org.apache.brooklyn.location.basic.MultiLocationResolver
+org.apache.brooklyn.location.core.DefinedLocationByIdResolver
+org.apache.brooklyn.location.core.NamedLocationResolver
+org.apache.brooklyn.location.core.CatalogLocationResolver
+org.apache.brooklyn.location.localhost.LocalhostLocationResolver
+org.apache.brooklyn.location.byon.ByonLocationResolver
+org.apache.brooklyn.location.byon.SingleMachineLocationResolver
+org.apache.brooklyn.location.byon.HostLocationResolver
+org.apache.brooklyn.location.core.MultiLocationResolver
 org.apache.brooklyn.location.access.PortForwardManagerLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
index df2167b..d3dc84b 100644
--- a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
+++ b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
@@ -32,7 +32,7 @@ import org.apache.brooklyn.core.config.SetConfigKey.SetModifications
 import org.apache.brooklyn.core.test.entity.TestApplication
 import org.apache.brooklyn.core.test.entity.TestEntity
 import org.apache.brooklyn.entity.core.Entities
-import org.apache.brooklyn.location.basic.SimulatedLocation
+import org.apache.brooklyn.location.core.SimulatedLocation
 import org.apache.brooklyn.sensor.core.DependentConfiguration
 import org.apache.brooklyn.util.collections.MutableMap
 import org.apache.brooklyn.util.core.task.DeferredSupplier

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerFileBasedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerFileBasedTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerFileBasedTest.java
index 98f429d..85e0e29 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerFileBasedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerFileBasedTest.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.core.mgmt.ha;
 
 import java.io.File;
 
-import org.apache.brooklyn.core.mgmt.rebind.persister.FileBasedObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.FileBasedObjectStore;
 import org.apache.brooklyn.util.os.Os;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
index 6eea03b..a8c532a 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryIntegrationTest.java
@@ -18,8 +18,8 @@
  */
 package org.apache.brooklyn.core.mgmt.ha;
 
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryTest.java
index c82f9cf..6970c2e 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerInMemoryTest.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
 import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.entity.core.EntityInternal;
@@ -38,8 +38,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 
 import com.google.common.collect.Iterables;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
index 71c7f94..fa90cbd 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
@@ -39,12 +39,12 @@ import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.ha.TestEntityFailingRebind.RebindException;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.ListeningObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
-import org.apache.brooklyn.core.mgmt.rebind.persister.BrooklynMementoPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.ListeningObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistMode;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.entity.core.Entities;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerTestFixture.java
index 1fb71ed..5130a58 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerTestFixture.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerTestFixture.java
@@ -37,13 +37,13 @@ import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordDeltaImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl.PromotionListener;
+import org.apache.brooklyn.core.mgmt.ha.dto.BasicManagementNodeSyncRecord;
+import org.apache.brooklyn.core.mgmt.ha.dto.BasicManagementNodeSyncRecord.Builder;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
-import org.apache.brooklyn.core.mgmt.rebind.persister.BrooklynMementoPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistMode;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.plane.dto.BasicManagementNodeSyncRecord;
-import org.apache.brooklyn.core.mgmt.rebind.plane.dto.BasicManagementNodeSyncRecord.Builder;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.entity.core.Entities;
 import org.apache.brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
index 2d5b3d2..89a0889 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
@@ -42,16 +42,16 @@ import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.ListeningObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixture;
 import org.apache.brooklyn.core.mgmt.rebind.RebindFeedTest.MyEntityWithFunctionFeedImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindFeedTest.MyEntityWithNewFeedsEachTimeImpl;
-import org.apache.brooklyn.core.mgmt.rebind.persister.BrooklynMementoPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.ListeningObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistMode;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
@@ -70,7 +70,7 @@ import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation.LocalhostMachine;
 
 import com.google.common.collect.Iterables;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/ManagementPlaneSyncRecordPersisterInMemory.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/ManagementPlaneSyncRecordPersisterInMemory.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/ManagementPlaneSyncRecordPersisterInMemory.java
index 4696ce9..208a3d0 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/ManagementPlaneSyncRecordPersisterInMemory.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/ManagementPlaneSyncRecordPersisterInMemory.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementNodeSyncRecord;
 import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecord;
 import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecordPersister;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
 import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/MasterChooserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/MasterChooserTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/MasterChooserTest.java
index da3f826..1ffbe1b 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/MasterChooserTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/MasterChooserTest.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementNodeSyncRecord;
 import org.apache.brooklyn.core.BrooklynVersion;
 import org.apache.brooklyn.core.mgmt.ha.BasicMasterChooser.AlphabeticMasterChooser;
 import org.apache.brooklyn.core.mgmt.ha.BasicMasterChooser.ScoredRecord;
-import org.apache.brooklyn.core.mgmt.rebind.plane.dto.BasicManagementNodeSyncRecord;
+import org.apache.brooklyn.core.mgmt.ha.dto.BasicManagementNodeSyncRecord;
 import org.apache.brooklyn.entity.core.EntityFunctions;
 import org.apache.brooklyn.util.time.Duration;
 import org.testng.annotations.BeforeMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
index d1c99d6..ab76e19 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
@@ -31,12 +31,12 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecordPersister;
 import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.InMemoryObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.ListeningObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
-import org.apache.brooklyn.core.mgmt.rebind.persister.BrooklynMementoPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.InMemoryObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.ListeningObjectStore;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistMode;
-import org.apache.brooklyn.core.mgmt.rebind.persister.PersistenceObjectStore;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.entity.core.Entities;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/AccessManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/AccessManagerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/AccessManagerTest.java
index 3fd4e24..74dbe56 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/AccessManagerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/AccessManagerTest.java
@@ -36,7 +36,7 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.core.SimulatedLocation;
 
 import com.google.common.collect.ImmutableSet;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterFileBasedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterFileBasedTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterFileBasedTest.java
new file mode 100644
index 0000000..e663f05
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterFileBasedTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.mgmt.persist;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.mgmt.persist.FileBasedObjectStore;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+/**
+ * @author Andrea Turli
+ */
+@Test
+public class BrooklynMementoPersisterFileBasedTest extends BrooklynMementoPersisterTestFixture {
+
+    protected File mementoDir;
+    
+    @Override
+    protected ManagementContext newPersistingManagementContext() {
+        mementoDir = Os.newTempDir(JavaClassNames.cleanSimpleClassName(this));
+        Os.deleteOnExitRecursively(mementoDir);
+        return RebindTestUtils.managementContextBuilder(classLoader, new FileBasedObjectStore(mementoDir))
+            .persistPeriod(Duration.millis(10)).buildStarted();
+    }
+
+    @Override
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        super.tearDown();
+        mementoDir = Os.deleteRecursively(mementoDir).asNullOrThrowing();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemorySizeIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
new file mode 100644
index 0000000..0c49d12
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.core.mgmt.persist;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.mgmt.persist.ListeningObjectStore.RecordingTransactionListener;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.entity.core.EntityInternal;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/** uses recorder to ensure not too much data is written */
+@Test
+public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends BrooklynMementoPersisterTestFixture {
+
+    protected RecordingTransactionListener recorder;
+    
+    protected ManagementContext newPersistingManagementContext() {
+        recorder = new RecordingTransactionListener("in-mem-test-"+Identifiers.makeRandomId(4));
+        return RebindTestUtils.managementContextBuilder(classLoader, 
+            new ListeningObjectStore(new InMemoryObjectStore(), recorder))
+            .persistPeriod(Duration.millis(100)).buildStarted();
+    }
+    
+    public void testPersistenceVolumeFast() throws IOException, TimeoutException, InterruptedException {
+        doTestPersistenceVolume(50*1000, false, true);
+    }
+    @Test(groups="Integration",invocationCount=20)
+    public void testPersistenceVolumeFastManyTimes() throws IOException, TimeoutException, InterruptedException {
+        doTestPersistenceVolume(50*1000, false, true);
+    }
+    @Test(groups="Integration")
+    public void testPersistenceVolumeWaiting() throws IOException, TimeoutException, InterruptedException {
+        // by waiting we ensure there aren't extra writes going on
+        doTestPersistenceVolume(50*1000, true, true);
+    }
+    public void testPersistenceVolumeFastNoTrigger() throws IOException, TimeoutException, InterruptedException {
+        doTestPersistenceVolume(50*1000, false, false);
+    }
+    @Test(groups="Integration",invocationCount=20)
+    public void testPersistenceVolumeFastNoTriggerManyTimes() throws IOException, TimeoutException, InterruptedException {
+        doTestPersistenceVolume(50*1000, false, false);
+    }
+    
+    protected void doTestPersistenceVolume(int bigBlockSize, boolean forceDelay, boolean canTrigger) throws IOException, TimeoutException, InterruptedException {
+        if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
+        else recorder.blockUntilDataWrittenExceeds(512, Duration.FIVE_SECONDS);
+        localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS, canTrigger);
+        
+        long out1 = recorder.getBytesOut();
+        int filesOut1 = recorder.getCountDataOut();
+        Assert.assertTrue(out1>512, "should have written at least 0.5k, only wrote "+out1);
+        Assert.assertTrue(out1<30*1000, "should have written less than 30k, wrote "+out1);
+        Assert.assertTrue(filesOut1<30, "should have written fewer than 30 files, wrote "+out1);
+        
+        ((EntityInternal)app).setAttribute(TestEntity.NAME, "hello world");
+        if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
+        else recorder.blockUntilDataWrittenExceeds(out1+10, Duration.FIVE_SECONDS);
+        localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS, canTrigger);
+        
+        long out2 = recorder.getBytesOut();
+        Assert.assertTrue(out2-out1>10, "should have written more data");
+        int filesOut2 = recorder.getCountDataOut();
+        Assert.assertTrue(filesOut2>filesOut1, "should have written more files");
+        
+        Assert.assertTrue(out2<50*1000, "should have written less than 50k, wrote "+out1);
+        Assert.assertTrue(filesOut2<40, "should have written fewer than 40 files, wrote "+out1);
+        
+        ((EntityInternal)entity).setAttribute(TestEntity.NAME, Identifiers.makeRandomId(bigBlockSize));
+        if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
+        else recorder.blockUntilDataWrittenExceeds(out2+bigBlockSize, Duration.FIVE_SECONDS);
+        localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS, canTrigger);
+
+        long out3 = recorder.getBytesOut();
+        Assert.assertTrue(out3-out2 > bigBlockSize, "should have written 50k more data, only wrote "+out3+" compared with "+out2);
+        int filesOut3 = recorder.getCountDataOut();
+        Assert.assertTrue(filesOut3>filesOut2, "should have written more files");
+        
+        Assert.assertTrue(out2<100*1000+bigBlockSize, "should have written less than 100k+block, wrote "+out1);
+        Assert.assertTrue(filesOut2<60, "should have written fewer than 60 files, wrote "+out1);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemoryTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemoryTest.java
new file mode 100644
index 0000000..461ec99
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterInMemoryTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.mgmt.persist;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.Test;
+
+@Test
+public class BrooklynMementoPersisterInMemoryTest extends BrooklynMementoPersisterTestFixture {
+
+    protected ManagementContext newPersistingManagementContext() {
+        return RebindTestUtils.managementContextBuilder(classLoader, new InMemoryObjectStore())
+            .persistPeriod(Duration.millis(10)).buildStarted();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
new file mode 100644
index 0000000..a715d2e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
@@ -0,0 +1,165 @@
+/*
+ * 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.core.mgmt.persist;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.mgmt.rebind.RebindManager.RebindFailureMode;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMemento;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
+import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
+import org.apache.brooklyn.core.mgmt.rebind.RebindContextImpl;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.mgmt.rebind.RecordingRebindExceptionHandler;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.core.test.policy.TestPolicy;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.sensor.enricher.Enrichers;
+import org.testng.SkipException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Andrea Turli
+ */
+public abstract class BrooklynMementoPersisterTestFixture {
+
+    protected ClassLoader classLoader = getClass().getClassLoader();
+    protected BrooklynMementoPersister persister;
+    protected TestApplication app;
+    protected Entity entity;
+    protected Location location;
+    protected ManagementContext localManagementContext;
+    protected Enricher enricher;
+    protected Policy policy;
+    
+    protected PersistenceObjectStore objectStore;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        localManagementContext = newPersistingManagementContext();
+        if (persister==null) {
+            persister = localManagementContext.getRebindManager().getPersister();
+        }
+        if (objectStore==null && persister instanceof BrooklynMementoPersisterToObjectStore) {
+            objectStore = ((BrooklynMementoPersisterToObjectStore)persister).getObjectStore();
+        }
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class), localManagementContext);
+        location =  localManagementContext.getLocationManager()
+            .createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", "localhost"));
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(location));
+        enricher = app.addEnricher(Enrichers.builder().propagatingAll().from(entity).build());
+        app.addPolicy(policy = new TestPolicy());
+    }
+
+    protected abstract ManagementContext newPersistingManagementContext();
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (localManagementContext != null) Entities.destroyAll(localManagementContext);
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        if (persister != null) persister.stop(false);
+        if (objectStore!=null) objectStore.deleteCompletely();
+        persister = null;
+    }
+
+    protected BrooklynMemento loadMemento() throws Exception {
+        RebindTestUtils.waitForPersisted(localManagementContext);
+        
+        RecordingRebindExceptionHandler failFast = new RecordingRebindExceptionHandler(RebindFailureMode.FAIL_FAST, RebindFailureMode.FAIL_FAST);
+        RebindContextImpl rebindContext = new RebindContextImpl(localManagementContext, failFast, classLoader);
+        // here we force these two to be reegistered in order to resolve the enricher and policy
+        // (normally rebind will do that after loading the manifests, but in this test we are just looking at persistence/manifest)
+        rebindContext.registerEntity(app.getId(), app);
+        rebindContext.registerEntity(entity.getId(), entity);
+        
+        BrooklynMemento reloadedMemento = persister.loadMemento(null, rebindContext.lookup(), failFast);
+        return reloadedMemento;
+    }
+    
+    protected BrooklynMementoRawData loadRawMemento(BrooklynMementoPersisterToObjectStore persister) throws Exception {
+        RebindTestUtils.waitForPersisted(localManagementContext);
+        
+        RecordingRebindExceptionHandler failFast = new RecordingRebindExceptionHandler(RebindFailureMode.FAIL_FAST, RebindFailureMode.FAIL_FAST);
+        BrooklynMementoRawData rawMemento = persister.loadMementoRawData(failFast);
+        return rawMemento;
+    }
+    
+    @Test
+    public void testCheckPointAndLoadMemento() throws Exception {
+        BrooklynMemento reloadedMemento = loadMemento();
+        
+        assertNotNull(reloadedMemento);
+        assertTrue(Iterables.contains(reloadedMemento.getEntityIds(), entity.getId()));
+        assertEquals(Iterables.getOnlyElement(reloadedMemento.getLocationIds()), location.getId());
+        assertEquals(Iterables.getOnlyElement(reloadedMemento.getPolicyIds()), policy.getId());
+        assertTrue(reloadedMemento.getEnricherIds().contains(enricher.getId()));
+    }
+
+    @Test
+    public void testDeleteAndLoadMemento() throws Exception {
+        Entities.destroy(entity);
+
+        BrooklynMemento reloadedMemento = loadMemento();
+        
+        assertNotNull(reloadedMemento);
+        assertFalse(Iterables.contains(reloadedMemento.getEntityIds(), entity.getId()));
+        assertEquals(Iterables.getOnlyElement(reloadedMemento.getLocationIds()), location.getId());
+    }
+    
+    @Test
+    public void testLoadAndCheckpointRawMemento() throws Exception {
+        if (persister instanceof BrooklynMementoPersisterToObjectStore) {
+            // Test loading
+            BrooklynMementoRawData rawMemento = loadRawMemento((BrooklynMementoPersisterToObjectStore)persister);
+            assertNotNull(rawMemento);
+            assertTrue(Iterables.contains(rawMemento.getEntities().keySet(), entity.getId()));
+            assertEquals(Iterables.getOnlyElement(rawMemento.getLocations().keySet()), location.getId());
+            assertEquals(Iterables.getOnlyElement(rawMemento.getPolicies().keySet()), policy.getId());
+            assertTrue(rawMemento.getEnrichers().keySet().contains(enricher.getId()));
+            
+            // And test persisting
+            PersistenceExceptionHandler exceptionHandler = PersistenceExceptionHandlerImpl.builder().build();
+            ((BrooklynMementoPersisterToObjectStore) persister).checkpoint(rawMemento, exceptionHandler);
+        } else {
+            throw new SkipException("Persister "+persister+" not a "+BrooklynMementoPersisterToObjectStore.class.getSimpleName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedObjectStoreTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedObjectStoreTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedObjectStoreTest.java
new file mode 100644
index 0000000..05ac078
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedObjectStoreTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.core.mgmt.persist;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
+import org.apache.brooklyn.core.mgmt.persist.FileBasedObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.util.io.FileUtil;
+import org.apache.brooklyn.util.os.Os;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.io.Files;
+
+public class FileBasedObjectStoreTest {
+
+    private LocalManagementContextForTests mgmt;
+    private File parentdir;
+    private File basedir;
+    private FileBasedObjectStore store;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = new LocalManagementContextForTests();
+        parentdir = Files.createTempDir();
+        basedir = new File(parentdir, "mystore");
+        store = new FileBasedObjectStore(basedir);
+        store.injectManagementContext(mgmt);
+        store.prepareForSharedUse(PersistMode.AUTO, HighAvailabilityMode.DISABLED);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (store != null) store.close();
+        if (parentdir != null) Os.deleteRecursively(basedir);
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+    
+    @Test(groups="Integration")
+    public void testSubPathCreatedWithPermission700() throws Exception {
+        store.createSubPath("mysubdir");
+        File subdir = new File(basedir, "mysubdir");
+        
+        assertFilePermission700(basedir);
+        assertFilePermission700(subdir);
+    }
+    
+    @Test
+    public void testIsMementoDirExistsButEmpty() throws Exception {
+        basedir = new File(parentdir, "testIsMementoDirExistsButEmpty");
+        assertFalse(FileBasedObjectStore.isMementoDirExistButEmpty(basedir));
+        assertFalse(FileBasedObjectStore.isMementoDirExistButEmpty(basedir.getAbsolutePath()));
+        
+        basedir.mkdir();
+        assertTrue(FileBasedObjectStore.isMementoDirExistButEmpty(basedir));
+        assertTrue(FileBasedObjectStore.isMementoDirExistButEmpty(basedir.getAbsolutePath()));
+        
+        new File(basedir, "entities").mkdir();
+        new File(basedir, "locations").mkdir();
+        assertTrue(FileBasedObjectStore.isMementoDirExistButEmpty(basedir));
+        assertTrue(FileBasedObjectStore.isMementoDirExistButEmpty(basedir.getAbsolutePath()));
+        
+        new File(new File(basedir, "locations"), "afile").createNewFile();
+        assertFalse(FileBasedObjectStore.isMementoDirExistButEmpty(basedir));
+        assertFalse(FileBasedObjectStore.isMementoDirExistButEmpty(basedir.getAbsolutePath()));
+    }
+    
+    static void assertFilePermission700(File file) throws FileNotFoundException {
+        assertEquals(FileUtil.getFilePermissions(file).get().substring(1), "rwx------");
+    }
+    
+    static void assertFilePermission600(File file) throws Exception {
+        assertEquals(FileUtil.getFilePermissions(file).get().substring(1), "rw-------");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessorWriterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessorWriterTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessorWriterTest.java
new file mode 100644
index 0000000..3ee71df
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessorWriterTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.mgmt.persist;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.brooklyn.core.mgmt.persist.FileBasedStoreObjectAccessor;
+import org.apache.brooklyn.core.mgmt.persist.StoreObjectAccessorLocking;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore.StoreObjectAccessorWithLock;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Files;
+
+@Test
+public class FileBasedStoreObjectAccessorWriterTest extends PersistenceStoreObjectAccessorWriterTestFixture {
+
+    private File file;
+    
+    protected StoreObjectAccessorWithLock newPersistenceStoreObjectAccessor() throws IOException {
+        file = Os.newTempFile(getClass(), "txt");
+        return new StoreObjectAccessorLocking(new FileBasedStoreObjectAccessor(file, ".tmp"));
+    }
+    
+    @Override
+    protected Duration getLastModifiedResolution() {
+        // OSX is 1s, Windows FAT is 2s !
+        return Duration.seconds(2);
+    }
+    
+    @Test(groups="Integration")
+    public void testLastModifiedTime() throws Exception {
+        super.testLastModifiedTime();
+    }
+    
+    @Test(groups="Integration")
+    public void testFilePermissions600() throws Exception {
+        accessor.put("abc");
+        assertEquals(Files.readLines(file, Charsets.UTF_8), ImmutableList.of("abc"));
+        
+        FileBasedObjectStoreTest.assertFilePermission600(file);
+    }
+}


Mime
View raw message