You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/07 01:59:56 UTC

[5/6] incubator-brooklyn git commit: package rename to org.apache.brooklyn: sandbox

package rename to org.apache.brooklyn: sandbox


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

Branch: refs/heads/master
Commit: 070b5ca7c85ec8819c2208c5fa7802af783edf1e
Parents: 08662a7
Author: Aled Sage <al...@gmail.com>
Authored: Thu Aug 6 11:43:58 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 6 17:17:54 2015 +0100

----------------------------------------------------------------------
 .../customsnitch/MultiCloudSnitch.java          | 222 ---------
 .../customsnitch/MultiCloudSnitch.java          | 222 +++++++++
 .../brooklyn/entity/database/Database.groovy    |  53 ---
 .../entity/database/derby/DerbyDatabase.java    | 172 -------
 .../database/derby/DerbyDatabaseDriver.java     |  25 -
 .../database/derby/DerbyDatabaseSshDriver.java  | 116 -----
 .../entity/database/derby/DerbySchema.java      | 147 ------
 .../brooklyn/entity/database/Database.groovy    |  53 +++
 .../entity/database/derby/DerbyDatabase.java    | 172 +++++++
 .../database/derby/DerbyDatabaseDriver.java     |  25 +
 .../database/derby/DerbyDatabaseSshDriver.java  | 116 +++++
 .../entity/database/derby/DerbySchema.java      | 148 ++++++
 .../entity/database/PlaceholderTest.java        |  26 --
 .../entity/database/PlaceholderTest.java        |  26 ++
 .../postgresql/PostgreSqlNodeSaltImpl.java      | 177 -------
 .../brooklyn/entity/salt/SaltBashCommands.java  |  92 ----
 .../java/brooklyn/entity/salt/SaltConfig.java   | 100 ----
 .../java/brooklyn/entity/salt/SaltConfigs.java  |  89 ----
 .../entity/salt/SaltLifecycleEffectorTasks.java | 220 ---------
 .../brooklyn/entity/salt/SaltStackMaster.java   |  70 ---
 .../entity/salt/SaltStackMasterDriver.java      |  25 -
 .../entity/salt/SaltStackMasterImpl.java        |  56 ---
 .../entity/salt/SaltStackMasterSshDriver.java   |  95 ----
 .../java/brooklyn/entity/salt/SaltTasks.java    | 145 ------
 .../postgresql/PostgreSqlNodeSaltImpl.java      | 179 +++++++
 .../brooklyn/entity/salt/SaltBashCommands.java  |  92 ++++
 .../apache/brooklyn/entity/salt/SaltConfig.java | 100 ++++
 .../brooklyn/entity/salt/SaltConfigs.java       |  89 ++++
 .../entity/salt/SaltLifecycleEffectorTasks.java | 220 +++++++++
 .../brooklyn/entity/salt/SaltStackMaster.java   |  70 +++
 .../entity/salt/SaltStackMasterDriver.java      |  25 +
 .../entity/salt/SaltStackMasterImpl.java        |  56 +++
 .../entity/salt/SaltStackMasterSshDriver.java   |  95 ++++
 .../apache/brooklyn/entity/salt/SaltTasks.java  | 145 ++++++
 .../main/resources/brooklyn/entity/salt/master  |  65 ---
 .../resources/brooklyn/entity/salt/masterless   |  53 ---
 .../main/resources/brooklyn/entity/salt/minion  |  52 ---
 .../org/apache/brooklyn/entity/salt/master      |  65 +++
 .../org/apache/brooklyn/entity/salt/masterless  |  53 +++
 .../org/apache/brooklyn/entity/salt/minion      |  52 +++
 .../postgresql/PostgreSqlSaltLiveTest.java      | 109 -----
 .../brooklyn/entity/salt/SaltConfigsTest.java   |  69 ---
 .../entity/salt/SaltLiveTestSupport.java        |  68 ---
 .../postgresql/PostgreSqlSaltLiveTest.java      | 112 +++++
 .../brooklyn/entity/salt/SaltConfigsTest.java   |  71 +++
 .../entity/salt/SaltLiveTestSupport.java        |  68 +++
 .../entity/monitoring/zabbix/ZabbixFeed.java    | 463 -------------------
 .../monitoring/zabbix/ZabbixMonitored.java      |  38 --
 .../monitoring/zabbix/ZabbixPollConfig.java     |  75 ---
 .../entity/monitoring/zabbix/ZabbixServer.java  |  52 ---
 .../monitoring/zabbix/ZabbixServerImpl.java     | 143 ------
 .../entity/monitoring/zabbix/ZabbixFeed.java    | 463 +++++++++++++++++++
 .../monitoring/zabbix/ZabbixMonitored.java      |  38 ++
 .../monitoring/zabbix/ZabbixPollConfig.java     |  75 +++
 .../entity/monitoring/zabbix/ZabbixServer.java  |  52 +++
 .../monitoring/zabbix/ZabbixServerImpl.java     | 143 ++++++
 sandbox/nosql/pom.xml                           |   2 +-
 .../nosql/hazelcast/HazelcastCluster.java       |  59 ---
 .../nosql/hazelcast/HazelcastClusterImpl.java   | 124 -----
 .../entity/nosql/hazelcast/HazelcastNode.java   |  97 ----
 .../nosql/hazelcast/HazelcastNodeDriver.java    |  25 -
 .../nosql/hazelcast/HazelcastNodeImpl.java      | 148 ------
 .../nosql/hazelcast/HazelcastNodeSshDriver.java | 159 -------
 .../nosql/infinispan/Infinispan5Driver.java     |  23 -
 .../nosql/infinispan/Infinispan5Server.java     |  88 ----
 .../nosql/infinispan/Infinispan5SshDriver.java  | 124 -----
 .../nosql/hazelcast/HazelcastCluster.java       |  59 +++
 .../nosql/hazelcast/HazelcastClusterImpl.java   | 124 +++++
 .../entity/nosql/hazelcast/HazelcastNode.java   |  97 ++++
 .../nosql/hazelcast/HazelcastNodeDriver.java    |  25 +
 .../nosql/hazelcast/HazelcastNodeImpl.java      | 148 ++++++
 .../nosql/hazelcast/HazelcastNodeSshDriver.java | 159 +++++++
 .../nosql/infinispan/Infinispan5Driver.java     |  23 +
 .../nosql/infinispan/Infinispan5Server.java     |  88 ++++
 .../nosql/infinispan/Infinispan5SshDriver.java  | 124 +++++
 .../nosql/hazelcast/hazelcast-brooklyn.xml      |  65 ---
 .../nosql/hazelcast/hazelcast-brooklyn.xml      |  65 +++
 .../hazelcast/HazelcastClusterEc2LiveTest.java  |  71 ---
 .../HazelcastClusterSoftlayerLiveTest.java      |  71 ---
 .../Infinispan5ServerIntegrationTest.groovy     | 102 ----
 .../hazelcast/HazelcastClusterEc2LiveTest.java  |  73 +++
 .../HazelcastClusterSoftlayerLiveTest.java      |  73 +++
 .../Infinispan5ServerIntegrationTest.groovy     | 103 +++++
 83 files changed, 4187 insertions(+), 4174 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/cassandra-multicloud-snitch/src/main/java/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
----------------------------------------------------------------------
diff --git a/sandbox/cassandra-multicloud-snitch/src/main/java/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java b/sandbox/cassandra-multicloud-snitch/src/main/java/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
deleted file mode 100644
index ada56e2..0000000
--- a/sandbox/cassandra-multicloud-snitch/src/main/java/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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 brooklyn.entity.nosql.cassandra.customsnitch;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Properties;
-
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.gms.ApplicationState;
-import org.apache.cassandra.gms.EndpointState;
-import org.apache.cassandra.gms.Gossiper;
-import org.apache.cassandra.gms.IEndpointStateChangeSubscriber;
-import org.apache.cassandra.gms.VersionedValue;
-import org.apache.cassandra.io.util.FileUtils;
-import org.apache.cassandra.locator.AbstractNetworkTopologySnitch;
-import org.apache.cassandra.net.MessagingService;
-import org.apache.cassandra.service.StorageService;
-import org.apache.cassandra.utils.FBUtilities;
-import org.apache.cassandra.utils.ResourceWatcher;
-import org.apache.cassandra.utils.WrappedRunnable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A snitch that can be configured to work across clouds. It uses and
- * extends the cassandra-rackdc.properties (which is used by the 
- * GossipingPropertyFileSnitch) to add a publicip and privateip 
- * configuration.
- * <p>
- * The code is very similar to Ec2MultiRegionSnitch, except that it uses
- * the the config file rather than querying EC2 to get the IPs.
- * <p>
- * If two nodes are in the same datacenter, they will attempt to communicate
- * using the privateip. If they are in different datacenters, they will use
- * the publicip.
- */
-public class MultiCloudSnitch extends AbstractNetworkTopologySnitch implements IEndpointStateChangeSubscriber
-{
-    // FIXME Need to submit a pull request to Cassandra (1.2.x branch) for this snitch.
-    // Or could enhance GossipingPropertyFileSnitch instead, and submit PR for that.
-    
-    protected static final Logger logger = LoggerFactory.getLogger(MultiCloudSnitch.class);
-    
-    public static final String SNITCH_PROPERTIES_FILENAME = "cassandra-rackdc.properties";
-
-    private static final String DEFAULT_DC = "UNKNOWN-DC";
-    private static final String DEFAULT_RACK = "UNKNOWN-RACK";
-    
-    protected String rack;
-    protected String datacenter;
-    protected InetAddress public_ip;
-    protected String private_ip;
-
-    private volatile boolean gossipStarted;
-
-    public MultiCloudSnitch() throws ConfigurationException
-    {
-        reloadConfiguration();
-        logger.info("CustomSnitch using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);
-
-        try
-        {
-            FBUtilities.resourceToFile(SNITCH_PROPERTIES_FILENAME);
-            Runnable runnable = new WrappedRunnable()
-            {
-                protected void runMayThrow() throws ConfigurationException
-                {
-                    reloadConfiguration();
-                }
-            };
-            ResourceWatcher.watch(SNITCH_PROPERTIES_FILENAME, runnable, 60 * 1000);
-        }
-        catch (ConfigurationException ex)
-        {
-            logger.debug(SNITCH_PROPERTIES_FILENAME + " found, but does not look like a plain file. Will not watch it for changes");
-        }
-    }
-
-    public void reloadConfiguration() throws ConfigurationException
-    {
-        HashMap<InetAddress, String[]> reloadedMap = new HashMap<InetAddress, String[]>();
-        String DC_PROPERTY = "dc";
-        String RACK_PROPERTY = "rack";
-        String PUBLIC_IP_PROPERTY = "publicip";
-        String PRIVATE_IP_PROPERTY = "privateip";
-
-        Properties properties = new Properties();
-        InputStream stream = null;
-        try
-        {
-            stream = getClass().getClassLoader().getResourceAsStream(SNITCH_PROPERTIES_FILENAME);
-            properties.load(stream);
-        }
-        catch (Exception e)
-        {
-            throw new ConfigurationException("Unable to read " + SNITCH_PROPERTIES_FILENAME, e);
-        }
-        finally
-        {
-            FileUtils.closeQuietly(stream);
-        }
-
-        datacenter = properties.getProperty(DC_PROPERTY);
-        rack = properties.getProperty(RACK_PROPERTY);
-        private_ip = checkNotNull(properties.getProperty(PRIVATE_IP_PROPERTY), "%s in %s", PRIVATE_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
-        String public_ip_str = checkNotNull(properties.getProperty(PUBLIC_IP_PROPERTY), "%s in %s", PUBLIC_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
-        try {
-            public_ip = InetAddress.getByName(public_ip_str);
-        }
-        catch (UnknownHostException e)
-        {
-            throw new ConfigurationException("Unknown host " + public_ip_str, e);
-        }
-        
-        logger.debug("CustomSnitch reloaded, using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);
-
-        if (StorageService.instance != null) // null check tolerates circular dependency; see CASSANDRA-4145
-            StorageService.instance.getTokenMetadata().invalidateCaches();
-
-        if (gossipStarted)
-            StorageService.instance.gossipSnitchInfo();
-    }
-
-
-    public String getRack(InetAddress endpoint)
-    {
-        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
-            return rack;
-        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
-        if (state == null || state.getApplicationState(ApplicationState.RACK) == null)
-            return DEFAULT_RACK;
-        return state.getApplicationState(ApplicationState.RACK).value;
-    }
-
-    public String getDatacenter(InetAddress endpoint)
-    {
-        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
-            return datacenter;
-        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
-        if (state == null || state.getApplicationState(ApplicationState.DC) == null)
-            return DEFAULT_DC;
-        return state.getApplicationState(ApplicationState.DC).value;
-    }
-    
-    public void onJoin(InetAddress endpoint, EndpointState epState)
-    {
-        if (epState.getApplicationState(ApplicationState.INTERNAL_IP) != null)
-            reConnect(endpoint, epState.getApplicationState(ApplicationState.INTERNAL_IP));
-    }
-
-    public void onChange(InetAddress endpoint, ApplicationState state, VersionedValue value)
-    {
-        if (state == ApplicationState.INTERNAL_IP)
-            reConnect(endpoint, value);
-    }
-
-    public void onAlive(InetAddress endpoint, EndpointState state)
-    {
-        if (state.getApplicationState(ApplicationState.INTERNAL_IP) != null)
-            reConnect(endpoint, state.getApplicationState(ApplicationState.INTERNAL_IP));
-    }
-
-    public void onDead(InetAddress endpoint, EndpointState state)
-    {
-        // do nothing
-    }
-
-    public void onRestart(InetAddress endpoint, EndpointState state)
-    {
-        // do nothing
-    }
-
-    public void onRemove(InetAddress endpoint)
-    {
-        // do nothing.
-    }
-
-    private void reConnect(InetAddress endpoint, VersionedValue versionedValue)
-    {
-        if (!getDatacenter(endpoint).equals(getDatacenter(public_ip)))
-            return; // do nothing return back...
-
-        try
-        {
-            InetAddress remoteIP = InetAddress.getByName(versionedValue.value);
-            MessagingService.instance().getConnectionPool(endpoint).reset(remoteIP);
-            logger.debug(String.format("Intiated reconnect to an Internal IP %s for the %s", remoteIP, endpoint));
-        } catch (UnknownHostException e)
-        {
-            logger.error("Error in getting the IP address resolved: ", e);
-        }
-    }
-
-    @Override
-    public void gossiperStarting()
-    {
-        super.gossiperStarting();
-        Gossiper.instance.addLocalApplicationState(ApplicationState.INTERNAL_IP, StorageService.instance.valueFactory.internalIP(private_ip));
-        Gossiper.instance.register(this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/cassandra-multicloud-snitch/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
----------------------------------------------------------------------
diff --git a/sandbox/cassandra-multicloud-snitch/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java b/sandbox/cassandra-multicloud-snitch/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
new file mode 100644
index 0000000..0199290
--- /dev/null
+++ b/sandbox/cassandra-multicloud-snitch/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/customsnitch/MultiCloudSnitch.java
@@ -0,0 +1,222 @@
+/*
+ * 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.entity.nosql.cassandra.customsnitch;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.gms.ApplicationState;
+import org.apache.cassandra.gms.EndpointState;
+import org.apache.cassandra.gms.Gossiper;
+import org.apache.cassandra.gms.IEndpointStateChangeSubscriber;
+import org.apache.cassandra.gms.VersionedValue;
+import org.apache.cassandra.io.util.FileUtils;
+import org.apache.cassandra.locator.AbstractNetworkTopologySnitch;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.utils.FBUtilities;
+import org.apache.cassandra.utils.ResourceWatcher;
+import org.apache.cassandra.utils.WrappedRunnable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A snitch that can be configured to work across clouds. It uses and
+ * extends the cassandra-rackdc.properties (which is used by the 
+ * GossipingPropertyFileSnitch) to add a publicip and privateip 
+ * configuration.
+ * <p>
+ * The code is very similar to Ec2MultiRegionSnitch, except that it uses
+ * the the config file rather than querying EC2 to get the IPs.
+ * <p>
+ * If two nodes are in the same datacenter, they will attempt to communicate
+ * using the privateip. If they are in different datacenters, they will use
+ * the publicip.
+ */
+public class MultiCloudSnitch extends AbstractNetworkTopologySnitch implements IEndpointStateChangeSubscriber
+{
+    // FIXME Need to submit a pull request to Cassandra (1.2.x branch) for this snitch.
+    // Or could enhance GossipingPropertyFileSnitch instead, and submit PR for that.
+    
+    protected static final Logger logger = LoggerFactory.getLogger(MultiCloudSnitch.class);
+    
+    public static final String SNITCH_PROPERTIES_FILENAME = "cassandra-rackdc.properties";
+
+    private static final String DEFAULT_DC = "UNKNOWN-DC";
+    private static final String DEFAULT_RACK = "UNKNOWN-RACK";
+    
+    protected String rack;
+    protected String datacenter;
+    protected InetAddress public_ip;
+    protected String private_ip;
+
+    private volatile boolean gossipStarted;
+
+    public MultiCloudSnitch() throws ConfigurationException
+    {
+        reloadConfiguration();
+        logger.info("CustomSnitch using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);
+
+        try
+        {
+            FBUtilities.resourceToFile(SNITCH_PROPERTIES_FILENAME);
+            Runnable runnable = new WrappedRunnable()
+            {
+                protected void runMayThrow() throws ConfigurationException
+                {
+                    reloadConfiguration();
+                }
+            };
+            ResourceWatcher.watch(SNITCH_PROPERTIES_FILENAME, runnable, 60 * 1000);
+        }
+        catch (ConfigurationException ex)
+        {
+            logger.debug(SNITCH_PROPERTIES_FILENAME + " found, but does not look like a plain file. Will not watch it for changes");
+        }
+    }
+
+    public void reloadConfiguration() throws ConfigurationException
+    {
+        HashMap<InetAddress, String[]> reloadedMap = new HashMap<InetAddress, String[]>();
+        String DC_PROPERTY = "dc";
+        String RACK_PROPERTY = "rack";
+        String PUBLIC_IP_PROPERTY = "publicip";
+        String PRIVATE_IP_PROPERTY = "privateip";
+
+        Properties properties = new Properties();
+        InputStream stream = null;
+        try
+        {
+            stream = getClass().getClassLoader().getResourceAsStream(SNITCH_PROPERTIES_FILENAME);
+            properties.load(stream);
+        }
+        catch (Exception e)
+        {
+            throw new ConfigurationException("Unable to read " + SNITCH_PROPERTIES_FILENAME, e);
+        }
+        finally
+        {
+            FileUtils.closeQuietly(stream);
+        }
+
+        datacenter = properties.getProperty(DC_PROPERTY);
+        rack = properties.getProperty(RACK_PROPERTY);
+        private_ip = checkNotNull(properties.getProperty(PRIVATE_IP_PROPERTY), "%s in %s", PRIVATE_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
+        String public_ip_str = checkNotNull(properties.getProperty(PUBLIC_IP_PROPERTY), "%s in %s", PUBLIC_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
+        try {
+            public_ip = InetAddress.getByName(public_ip_str);
+        }
+        catch (UnknownHostException e)
+        {
+            throw new ConfigurationException("Unknown host " + public_ip_str, e);
+        }
+        
+        logger.debug("CustomSnitch reloaded, using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);
+
+        if (StorageService.instance != null) // null check tolerates circular dependency; see CASSANDRA-4145
+            StorageService.instance.getTokenMetadata().invalidateCaches();
+
+        if (gossipStarted)
+            StorageService.instance.gossipSnitchInfo();
+    }
+
+
+    public String getRack(InetAddress endpoint)
+    {
+        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
+            return rack;
+        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
+        if (state == null || state.getApplicationState(ApplicationState.RACK) == null)
+            return DEFAULT_RACK;
+        return state.getApplicationState(ApplicationState.RACK).value;
+    }
+
+    public String getDatacenter(InetAddress endpoint)
+    {
+        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
+            return datacenter;
+        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
+        if (state == null || state.getApplicationState(ApplicationState.DC) == null)
+            return DEFAULT_DC;
+        return state.getApplicationState(ApplicationState.DC).value;
+    }
+    
+    public void onJoin(InetAddress endpoint, EndpointState epState)
+    {
+        if (epState.getApplicationState(ApplicationState.INTERNAL_IP) != null)
+            reConnect(endpoint, epState.getApplicationState(ApplicationState.INTERNAL_IP));
+    }
+
+    public void onChange(InetAddress endpoint, ApplicationState state, VersionedValue value)
+    {
+        if (state == ApplicationState.INTERNAL_IP)
+            reConnect(endpoint, value);
+    }
+
+    public void onAlive(InetAddress endpoint, EndpointState state)
+    {
+        if (state.getApplicationState(ApplicationState.INTERNAL_IP) != null)
+            reConnect(endpoint, state.getApplicationState(ApplicationState.INTERNAL_IP));
+    }
+
+    public void onDead(InetAddress endpoint, EndpointState state)
+    {
+        // do nothing
+    }
+
+    public void onRestart(InetAddress endpoint, EndpointState state)
+    {
+        // do nothing
+    }
+
+    public void onRemove(InetAddress endpoint)
+    {
+        // do nothing.
+    }
+
+    private void reConnect(InetAddress endpoint, VersionedValue versionedValue)
+    {
+        if (!getDatacenter(endpoint).equals(getDatacenter(public_ip)))
+            return; // do nothing return back...
+
+        try
+        {
+            InetAddress remoteIP = InetAddress.getByName(versionedValue.value);
+            MessagingService.instance().getConnectionPool(endpoint).reset(remoteIP);
+            logger.debug(String.format("Intiated reconnect to an Internal IP %s for the %s", remoteIP, endpoint));
+        } catch (UnknownHostException e)
+        {
+            logger.error("Error in getting the IP address resolved: ", e);
+        }
+    }
+
+    @Override
+    public void gossiperStarting()
+    {
+        super.gossiperStarting();
+        Gossiper.instance.addLocalApplicationState(ApplicationState.INTERNAL_IP, StorageService.instance.valueFactory.internalIP(private_ip));
+        Gossiper.instance.register(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/brooklyn/entity/database/Database.groovy
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/brooklyn/entity/database/Database.groovy b/sandbox/database/src/main/java/brooklyn/entity/database/Database.groovy
deleted file mode 100644
index a86c862..0000000
--- a/sandbox/database/src/main/java/brooklyn/entity/database/Database.groovy
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 brooklyn.entity.database
-
-import brooklyn.event.basic.BasicConfigKey
-
-/**
- * Intended to represent a SQL relational database service.
- *
- * TODO work in progress
- */
-public interface Database {
-    BasicConfigKey<String> SQL_VERSION = [ String, "database.sql.version", "SQL version" ]
-
-    Collection<Schema> getSchemas();
-
-    void createSchema(String name, Map properties);
-
-    void addSchema(Schema schema);
-
-    void removeSchema(String schemaName);
-}
-
-/**
- * Intended to represent a SQL database schema.
- *
- * TODO work in progress
- */
-public interface Schema {
-    BasicConfigKey<String> SCHEMA_NAME = [ String, "database.schema", "Database schema name" ]
-
-    void create();
-    
-    void remove();
-    
-    String getName();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabase.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabase.java b/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabase.java
deleted file mode 100644
index aad881f..0000000
--- a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabase.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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 brooklyn.entity.database.derby;
-
-import java.util.Collection;
-import java.util.Map;
-
-import javax.management.ObjectName;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.basic.SoftwareProcessImpl;
-import brooklyn.entity.database.Database;
-import brooklyn.entity.database.Schema;
-import brooklyn.entity.java.UsesJava;
-import brooklyn.entity.java.UsesJmx;
-import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.event.feed.jmx.JmxHelper;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * An {@link Entity} that represents a single Derby SQL database server instance.
- *
- * TODO work in progress
- */
-public class DerbyDatabase extends SoftwareProcessImpl implements Database, UsesJava, UsesJmx {
-    private static final Logger log = LoggerFactory.getLogger(DerbyDatabase.class);
-
-    @SetFromFlag("version")
-    public static final ConfigKey<String> SUGGESTED_VERSION =
-            ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "10.8.1.2");
-
-    public static final PortAttributeSensorAndConfigKey JDBC_PORT = new PortAttributeSensorAndConfigKey(
-            "derby.jdbcPort", "Suggested JDBC port");
-    
-    public static final ConfigKey<String> VIRTUAL_HOST_NAME = new BasicConfigKey<String>(
-            String.class, "derby.virtualHost", "Derby virtual host name", "localhost");
-
-    public static final BasicAttributeSensorAndConfigKey<String> JMX_USER = new BasicAttributeSensorAndConfigKey<String>(
-            UsesJmx.JMX_USER, "admin");
-    
-    public static final BasicAttributeSensorAndConfigKey<String> JMX_PASSWORD = new BasicAttributeSensorAndConfigKey<String>(
-            UsesJmx.JMX_PASSWORD, "admin");
-
-    @SetFromFlag
-    protected Collection<String> schemaNames;
-    
-    @SetFromFlag
-    protected Map<String, DerbySchema> schemas;
-
-    protected transient JmxHelper jmxHelper;
-    
-    public DerbyDatabase() {
-        this(MutableMap.of(), null);
-    }
-    public DerbyDatabase(Map properties) {
-        this(properties, null);
-    }
-    public DerbyDatabase(Entity parent) {
-        this(MutableMap.of(), parent);
-    }
-    public DerbyDatabase(Map properties, Entity parent) {
-        super(properties, parent);
-
-        if (schemaNames == null) schemaNames = Lists.newArrayList();
-        if (schemas == null) schemas = Maps.newLinkedHashMap();
-    }
-
-    @Override
-    public Class<? extends DerbyDatabaseDriver> getDriverInterface() {
-        return DerbyDatabaseDriver.class;
-    }
-
-    @Override
-    public void connectSensors() {
-        super.connectSensors();
-        connectServiceUpIsRunning();
-    }
-
-    @Override
-    public void disconnectSensors() {
-        super.disconnectSensors();
-        disconnectServiceUpIsRunning();
-    }
-
-    @Override
-    public void postStart() {
-        super.postStart();
-        for (String name : schemaNames) {
-            createSchema(name);
-        }
-    }
-
-    @Override
-    public void preStop() {
-        super.preStop();
-        for (DerbySchema schema : schemas.values()) {
-            schema.destroy();
-        }
-        if (jmxHelper != null) jmxHelper.terminate();
-    }
-
-    public void createSchema(String name) {
-        createSchema(name, ImmutableMap.of());
-    }
-    
-    public void createSchema(String name, Map properties) {
-        Map allprops = MutableMap.builder().putAll(properties).put("name", name).build();
-        DerbySchema schema = new DerbySchema(allprops);
-        schema.init();
-        schema.create();
-        schemas.put(name, schema);
-    }
-
-    public Collection<Schema> getSchemas() {
-        return ImmutableList.<Schema>copyOf(schemas.values());
-    }
-    
-    public void addSchema(Schema schema) {
-        schemas.put(schema.getName(), (DerbySchema) schema);
-    }
-    
-    public void removeSchema(String schemaName) {
-        schemas.remove(schemaName);
-    }
-
-    @Override
-    protected ToStringHelper toStringHelper() {
-        return super.toStringHelper().add("jdbcPort", getAttribute(JDBC_PORT));
-    }
-
-    protected boolean computeNodeUp() {
-        // FIXME Use the JmxAdapter.reachable() stuff instead of getAttribute
-        try {
-            ObjectName serverInfoObjectName = ObjectName.getInstance("org.apache.derby:type=ServerInformation,name=ServerInformation");
-            String productVersion = (String) jmxHelper.getAttribute(serverInfoObjectName, "ProductVersion");
-            return (productVersion != null);
-        } catch (Exception e) {
-            return false;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseDriver.java b/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
deleted file mode 100644
index ed76e78..0000000
--- a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 brooklyn.entity.database.derby;
-
-import brooklyn.entity.java.JavaSoftwareProcessDriver;
-
-public interface DerbyDatabaseDriver extends JavaSoftwareProcessDriver {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java b/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
deleted file mode 100644
index 172f823..0000000
--- a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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 brooklyn.entity.database.derby;
-
-import static java.lang.String.format;
-
-import java.util.List;
-import java.util.Map;
-
-import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.ssh.BashCommands;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Start a {@link DerbyDatabase} in a {@link Location} accessible over ssh.
- *
- * TODO work in progress
- */
-public class DerbyDatabaseSshDriver extends JavaSoftwareProcessSshDriver implements DerbyDatabaseDriver {
-
-    // TOD Previous comment said "JMX is configured using command line switch"; how should that be set here?
-
-    public DerbyDatabaseSshDriver(DerbyDatabase entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    public String getPidFile() { return "derby.pid"; }
-
-    @Override
-    protected String getLogFileLocation() {
-        throw new UnsupportedOperationException("Work in progress");
-    }
-
-    @Override
-    public void install() {
-        String url = format("http://www.mirrorservice.org/sites/ftp.apache.org/db/derby/db-derby-%s/db-derby-%s-lib.tar.gz", getVersion(), getVersion());
-        String saveAs = format("db-derby-%s-lib.tar.gz", getVersion());
-
-        List<String> commands = ImmutableList.<String>builder()
-                .add(BashCommands.commandToDownloadUrlAs(url, saveAs))
-                .add(BashCommands.INSTALL_TAR)
-                .add("tar xzfv " + saveAs)
-                .build();
-
-        newScript(INSTALLING)
-                .failOnNonZeroResultCode()
-                .body.append(commands).execute();
-    }
-
-    @Override
-    public void customize() {
-        newScript(CUSTOMIZING)
-                .failOnNonZeroResultCode()
-                .body.append(
-                        format("cp -R %s/derby-broker-%s/{bin,etc,lib} .", getInstallDir(), getVersion()),
-                        "make install PREFIX="+getRunDir())
-                .execute();
-    }
-    
-    @Override
-    public void launch() {
-        // TODO Should we redirect stdout/stderr: format(" >> %s/console 2>&1 </dev/null &", getRunDir())
-        newScript(MutableMap.of("usePidFile", getPidFile()), LAUNCHING)
-                .failOnNonZeroResultCode()
-                .body.append("nohup ./bin/derby &")
-                .execute();
-    }
- 
-
-    @Override
-    public boolean isRunning() {
-        return newScript(MutableMap.of("usePidFile", getPidFile()), CHECK_RUNNING)
-                .execute() == 0;
-    }
-
-    /**
-     * Restarts redis with the current configuration.
-     */
-    @Override
-    public void stop() {
-        newScript(MutableMap.of("usePidFile", getPidFile()), STOPPING)
-                .execute();
-    }
-
-    @Override
-    public Map<String, String> getShellEnvironment() {
-        Map<String, String> orig = super.getShellEnvironment();
-        
-        return MutableMap.<String, String>builder()
-                .putAll(orig)
-                .put("DERBY_HOME", getRunDir())
-                .put("DERBY_WORK", getRunDir())
-                .putIfNotNull("DERBY_OPTS", orig.get("JAVA_OPTS"))
-                .build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbySchema.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbySchema.java b/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbySchema.java
deleted file mode 100644
index 9ea26b5..0000000
--- a/sandbox/database/src/main/java/brooklyn/entity/database/derby/DerbySchema.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 brooklyn.entity.database.derby;
-
-import static java.lang.String.format;
-
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import javax.management.ObjectName;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.database.Schema;
-import brooklyn.entity.java.UsesJmx;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.event.feed.jmx.JmxAttributePollConfig;
-import brooklyn.event.feed.jmx.JmxFeed;
-import brooklyn.event.feed.jmx.JmxHelper;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.base.Objects.ToStringHelper;
-
-public class DerbySchema extends AbstractEntity implements Schema {
-
-    // FIXME Needs reviewed and implemented properly; while fixing compilation errors
-    // I added enough for it to look mostly plausible but it's completely untested.
-    // And I have not looked up the derby docs to check that the attributes etc are valid. 
-    
-    // TODO Somehow share jmx connection with DerbyDatabase instance
-    
-    // TODO Declare effectors
-    
-    public static AttributeSensor<Integer> SCHEMA_DEPTH = new BasicAttributeSensor<Integer>(
-            Integer.class, "derby.schema.depth", "schema depth");
-    
-    public static AttributeSensor<Integer> MESSAGE_COUNT = new BasicAttributeSensor<Integer>(
-            Integer.class, "derby.schema.messageCount", "message count");
-    
-    @SetFromFlag(defaultVal="localhost")
-    String virtualHost;
-    
-    @SetFromFlag(nullable=false)
-    String name;
-
-    protected ObjectName virtualHostManager;
-    protected ObjectName exchange;
-
-    transient JmxHelper jmxHelper;
-    transient JmxFeed jmxFeed;
-    
-    public DerbySchema() {
-        super(MutableMap.of(), null);
-    }
-    public DerbySchema(Map properties) {
-        super(properties, null);
-    }
-    public DerbySchema(Entity parent) {
-        this(MutableMap.of(), parent);
-    }
-    public DerbySchema(Map properties, Entity parent) {
-        super(properties, parent);
-    }
-    
-    @Override
-    public String getName() {
-        return name;
-    }
-    
-    @Override
-    public DerbyDatabase getParent() {
-        return (DerbyDatabase) super.getParent();
-    }
-    
-    /**
-     * Return the JDBC connection URL for the schema.
-     */
-    public String getConnectionUrl() { return String.format("jdbc:derby:%s", name); }
-
-    public void init() {
-        try {
-            virtualHostManager = new ObjectName(format("org.apache.derby:type=VirtualHost.VirtualHostManager,VirtualHost=\"%s\"", virtualHost));
-            exchange = new ObjectName(format("org.apache.derby:type=VirtualHost.Exchange,VirtualHost=\"%s\",name=\"amq.direct\",ExchangeType=direct", virtualHost));
-            create();
-
-            jmxHelper = new JmxHelper((EntityLocal)getParent());
-
-            ObjectName schemaMBeanName = new ObjectName(format("org.apache.derby:type=VirtualHost.Schema,VirtualHost=\"%s\",name=\"%s\"", virtualHost, name));
-
-            jmxFeed = JmxFeed.builder()
-                    .entity(this)
-                    .helper(jmxHelper)
-                    .period(500, TimeUnit.MILLISECONDS)
-                    .pollAttribute(new JmxAttributePollConfig<Integer>(SCHEMA_DEPTH)
-                            .objectName(schemaMBeanName)
-                            .attributeName("SchemaDepth"))
-                    .pollAttribute(new JmxAttributePollConfig<Integer>(MESSAGE_COUNT)
-                            .objectName(schemaMBeanName)
-                            .attributeName("MessageCount"))
-                    .build();
-            
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    public void create() {
-        jmxHelper.operation(virtualHostManager, "createNewSchema", name, getParent().getAttribute(UsesJmx.JMX_USER), true);
-        jmxHelper.operation(exchange, "createNewBinding", name, name);
-    }
-
-    public void remove() {
-        jmxHelper.operation(exchange, "removeBinding", name, name);
-        jmxHelper.operation(virtualHostManager, "deleteSchema", name);
-    }
-
-    @Override
-    public void destroy() {
-        if (jmxFeed != null) jmxFeed.stop();
-        super.destroy();
-    }
-
-    @Override
-    protected ToStringHelper toStringHelper() {
-        return super.toStringHelper().add("name", name);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/Database.groovy
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/Database.groovy b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/Database.groovy
new file mode 100644
index 0000000..5118dd0
--- /dev/null
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/Database.groovy
@@ -0,0 +1,53 @@
+/*
+ * 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.entity.database
+
+import brooklyn.event.basic.BasicConfigKey
+
+/**
+ * Intended to represent a SQL relational database service.
+ *
+ * TODO work in progress
+ */
+public interface Database {
+    BasicConfigKey<String> SQL_VERSION = [ String, "database.sql.version", "SQL version" ]
+
+    Collection<Schema> getSchemas();
+
+    void createSchema(String name, Map properties);
+
+    void addSchema(Schema schema);
+
+    void removeSchema(String schemaName);
+}
+
+/**
+ * Intended to represent a SQL database schema.
+ *
+ * TODO work in progress
+ */
+public interface Schema {
+    BasicConfigKey<String> SCHEMA_NAME = [ String, "database.schema", "Database schema name" ]
+
+    void create();
+    
+    void remove();
+    
+    String getName();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
new file mode 100644
index 0000000..00b0ab2
--- /dev/null
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
@@ -0,0 +1,172 @@
+/*
+ * 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.entity.database.derby;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.entity.database.Database;
+import org.apache.brooklyn.entity.database.Schema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.basic.SoftwareProcessImpl;
+import brooklyn.entity.java.UsesJava;
+import brooklyn.entity.java.UsesJmx;
+import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
+import brooklyn.event.feed.jmx.JmxHelper;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * An {@link Entity} that represents a single Derby SQL database server instance.
+ *
+ * TODO work in progress
+ */
+public class DerbyDatabase extends SoftwareProcessImpl implements Database, UsesJava, UsesJmx {
+    private static final Logger log = LoggerFactory.getLogger(DerbyDatabase.class);
+
+    @SetFromFlag("version")
+    public static final ConfigKey<String> SUGGESTED_VERSION =
+            ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "10.8.1.2");
+
+    public static final PortAttributeSensorAndConfigKey JDBC_PORT = new PortAttributeSensorAndConfigKey(
+            "derby.jdbcPort", "Suggested JDBC port");
+    
+    public static final ConfigKey<String> VIRTUAL_HOST_NAME = new BasicConfigKey<String>(
+            String.class, "derby.virtualHost", "Derby virtual host name", "localhost");
+
+    public static final BasicAttributeSensorAndConfigKey<String> JMX_USER = new BasicAttributeSensorAndConfigKey<String>(
+            UsesJmx.JMX_USER, "admin");
+    
+    public static final BasicAttributeSensorAndConfigKey<String> JMX_PASSWORD = new BasicAttributeSensorAndConfigKey<String>(
+            UsesJmx.JMX_PASSWORD, "admin");
+
+    @SetFromFlag
+    protected Collection<String> schemaNames;
+    
+    @SetFromFlag
+    protected Map<String, DerbySchema> schemas;
+
+    protected transient JmxHelper jmxHelper;
+    
+    public DerbyDatabase() {
+        this(MutableMap.of(), null);
+    }
+    public DerbyDatabase(Map properties) {
+        this(properties, null);
+    }
+    public DerbyDatabase(Entity parent) {
+        this(MutableMap.of(), parent);
+    }
+    public DerbyDatabase(Map properties, Entity parent) {
+        super(properties, parent);
+
+        if (schemaNames == null) schemaNames = Lists.newArrayList();
+        if (schemas == null) schemas = Maps.newLinkedHashMap();
+    }
+
+    @Override
+    public Class<? extends DerbyDatabaseDriver> getDriverInterface() {
+        return DerbyDatabaseDriver.class;
+    }
+
+    @Override
+    public void connectSensors() {
+        super.connectSensors();
+        connectServiceUpIsRunning();
+    }
+
+    @Override
+    public void disconnectSensors() {
+        super.disconnectSensors();
+        disconnectServiceUpIsRunning();
+    }
+
+    @Override
+    public void postStart() {
+        super.postStart();
+        for (String name : schemaNames) {
+            createSchema(name);
+        }
+    }
+
+    @Override
+    public void preStop() {
+        super.preStop();
+        for (DerbySchema schema : schemas.values()) {
+            schema.destroy();
+        }
+        if (jmxHelper != null) jmxHelper.terminate();
+    }
+
+    public void createSchema(String name) {
+        createSchema(name, ImmutableMap.of());
+    }
+    
+    public void createSchema(String name, Map properties) {
+        Map allprops = MutableMap.builder().putAll(properties).put("name", name).build();
+        DerbySchema schema = new DerbySchema(allprops);
+        schema.init();
+        schema.create();
+        schemas.put(name, schema);
+    }
+
+    public Collection<Schema> getSchemas() {
+        return ImmutableList.<Schema>copyOf(schemas.values());
+    }
+    
+    public void addSchema(Schema schema) {
+        schemas.put(schema.getName(), (DerbySchema) schema);
+    }
+    
+    public void removeSchema(String schemaName) {
+        schemas.remove(schemaName);
+    }
+
+    @Override
+    protected ToStringHelper toStringHelper() {
+        return super.toStringHelper().add("jdbcPort", getAttribute(JDBC_PORT));
+    }
+
+    protected boolean computeNodeUp() {
+        // FIXME Use the JmxAdapter.reachable() stuff instead of getAttribute
+        try {
+            ObjectName serverInfoObjectName = ObjectName.getInstance("org.apache.derby:type=ServerInformation,name=ServerInformation");
+            String productVersion = (String) jmxHelper.getAttribute(serverInfoObjectName, "ProductVersion");
+            return (productVersion != null);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseDriver.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
new file mode 100644
index 0000000..832c2b0
--- /dev/null
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseDriver.java
@@ -0,0 +1,25 @@
+/*
+ * 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.entity.database.derby;
+
+import brooklyn.entity.java.JavaSoftwareProcessDriver;
+
+public interface DerbyDatabaseDriver extends JavaSoftwareProcessDriver {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
new file mode 100644
index 0000000..32bc58c
--- /dev/null
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabaseSshDriver.java
@@ -0,0 +1,116 @@
+/*
+ * 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.entity.database.derby;
+
+import static java.lang.String.format;
+
+import java.util.List;
+import java.util.Map;
+
+import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
+import brooklyn.location.Location;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.ssh.BashCommands;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Start a {@link DerbyDatabase} in a {@link Location} accessible over ssh.
+ *
+ * TODO work in progress
+ */
+public class DerbyDatabaseSshDriver extends JavaSoftwareProcessSshDriver implements DerbyDatabaseDriver {
+
+    // TOD Previous comment said "JMX is configured using command line switch"; how should that be set here?
+
+    public DerbyDatabaseSshDriver(DerbyDatabase entity, SshMachineLocation machine) {
+        super(entity, machine);
+    }
+
+    public String getPidFile() { return "derby.pid"; }
+
+    @Override
+    protected String getLogFileLocation() {
+        throw new UnsupportedOperationException("Work in progress");
+    }
+
+    @Override
+    public void install() {
+        String url = format("http://www.mirrorservice.org/sites/ftp.apache.org/db/derby/db-derby-%s/db-derby-%s-lib.tar.gz", getVersion(), getVersion());
+        String saveAs = format("db-derby-%s-lib.tar.gz", getVersion());
+
+        List<String> commands = ImmutableList.<String>builder()
+                .add(BashCommands.commandToDownloadUrlAs(url, saveAs))
+                .add(BashCommands.INSTALL_TAR)
+                .add("tar xzfv " + saveAs)
+                .build();
+
+        newScript(INSTALLING)
+                .failOnNonZeroResultCode()
+                .body.append(commands).execute();
+    }
+
+    @Override
+    public void customize() {
+        newScript(CUSTOMIZING)
+                .failOnNonZeroResultCode()
+                .body.append(
+                        format("cp -R %s/derby-broker-%s/{bin,etc,lib} .", getInstallDir(), getVersion()),
+                        "make install PREFIX="+getRunDir())
+                .execute();
+    }
+    
+    @Override
+    public void launch() {
+        // TODO Should we redirect stdout/stderr: format(" >> %s/console 2>&1 </dev/null &", getRunDir())
+        newScript(MutableMap.of("usePidFile", getPidFile()), LAUNCHING)
+                .failOnNonZeroResultCode()
+                .body.append("nohup ./bin/derby &")
+                .execute();
+    }
+ 
+
+    @Override
+    public boolean isRunning() {
+        return newScript(MutableMap.of("usePidFile", getPidFile()), CHECK_RUNNING)
+                .execute() == 0;
+    }
+
+    /**
+     * Restarts redis with the current configuration.
+     */
+    @Override
+    public void stop() {
+        newScript(MutableMap.of("usePidFile", getPidFile()), STOPPING)
+                .execute();
+    }
+
+    @Override
+    public Map<String, String> getShellEnvironment() {
+        Map<String, String> orig = super.getShellEnvironment();
+        
+        return MutableMap.<String, String>builder()
+                .putAll(orig)
+                .put("DERBY_HOME", getRunDir())
+                .put("DERBY_WORK", getRunDir())
+                .putIfNotNull("DERBY_OPTS", orig.get("JAVA_OPTS"))
+                .build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
new file mode 100644
index 0000000..c4fb2b1
--- /dev/null
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
@@ -0,0 +1,148 @@
+/*
+ * 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.entity.database.derby;
+
+import static java.lang.String.format;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.entity.database.Schema;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.java.UsesJmx;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.BasicAttributeSensor;
+import brooklyn.event.feed.jmx.JmxAttributePollConfig;
+import brooklyn.event.feed.jmx.JmxFeed;
+import brooklyn.event.feed.jmx.JmxHelper;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.base.Objects.ToStringHelper;
+
+public class DerbySchema extends AbstractEntity implements Schema {
+
+    // FIXME Needs reviewed and implemented properly; while fixing compilation errors
+    // I added enough for it to look mostly plausible but it's completely untested.
+    // And I have not looked up the derby docs to check that the attributes etc are valid. 
+    
+    // TODO Somehow share jmx connection with DerbyDatabase instance
+    
+    // TODO Declare effectors
+    
+    public static AttributeSensor<Integer> SCHEMA_DEPTH = new BasicAttributeSensor<Integer>(
+            Integer.class, "derby.schema.depth", "schema depth");
+    
+    public static AttributeSensor<Integer> MESSAGE_COUNT = new BasicAttributeSensor<Integer>(
+            Integer.class, "derby.schema.messageCount", "message count");
+    
+    @SetFromFlag(defaultVal="localhost")
+    String virtualHost;
+    
+    @SetFromFlag(nullable=false)
+    String name;
+
+    protected ObjectName virtualHostManager;
+    protected ObjectName exchange;
+
+    transient JmxHelper jmxHelper;
+    transient JmxFeed jmxFeed;
+    
+    public DerbySchema() {
+        super(MutableMap.of(), null);
+    }
+    public DerbySchema(Map properties) {
+        super(properties, null);
+    }
+    public DerbySchema(Entity parent) {
+        this(MutableMap.of(), parent);
+    }
+    public DerbySchema(Map properties, Entity parent) {
+        super(properties, parent);
+    }
+    
+    @Override
+    public String getName() {
+        return name;
+    }
+    
+    @Override
+    public DerbyDatabase getParent() {
+        return (DerbyDatabase) super.getParent();
+    }
+    
+    /**
+     * Return the JDBC connection URL for the schema.
+     */
+    public String getConnectionUrl() { return String.format("jdbc:derby:%s", name); }
+
+    public void init() {
+        try {
+            virtualHostManager = new ObjectName(format("org.apache.derby:type=VirtualHost.VirtualHostManager,VirtualHost=\"%s\"", virtualHost));
+            exchange = new ObjectName(format("org.apache.derby:type=VirtualHost.Exchange,VirtualHost=\"%s\",name=\"amq.direct\",ExchangeType=direct", virtualHost));
+            create();
+
+            jmxHelper = new JmxHelper((EntityLocal)getParent());
+
+            ObjectName schemaMBeanName = new ObjectName(format("org.apache.derby:type=VirtualHost.Schema,VirtualHost=\"%s\",name=\"%s\"", virtualHost, name));
+
+            jmxFeed = JmxFeed.builder()
+                    .entity(this)
+                    .helper(jmxHelper)
+                    .period(500, TimeUnit.MILLISECONDS)
+                    .pollAttribute(new JmxAttributePollConfig<Integer>(SCHEMA_DEPTH)
+                            .objectName(schemaMBeanName)
+                            .attributeName("SchemaDepth"))
+                    .pollAttribute(new JmxAttributePollConfig<Integer>(MESSAGE_COUNT)
+                            .objectName(schemaMBeanName)
+                            .attributeName("MessageCount"))
+                    .build();
+            
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    public void create() {
+        jmxHelper.operation(virtualHostManager, "createNewSchema", name, getParent().getAttribute(UsesJmx.JMX_USER), true);
+        jmxHelper.operation(exchange, "createNewBinding", name, name);
+    }
+
+    public void remove() {
+        jmxHelper.operation(exchange, "removeBinding", name, name);
+        jmxHelper.operation(virtualHostManager, "deleteSchema", name);
+    }
+
+    @Override
+    public void destroy() {
+        if (jmxFeed != null) jmxFeed.stop();
+        super.destroy();
+    }
+
+    @Override
+    protected ToStringHelper toStringHelper() {
+        return super.toStringHelper().add("name", name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/test/java/brooklyn/entity/database/PlaceholderTest.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/test/java/brooklyn/entity/database/PlaceholderTest.java b/sandbox/database/src/test/java/brooklyn/entity/database/PlaceholderTest.java
deleted file mode 100644
index 55b5d22..0000000
--- a/sandbox/database/src/test/java/brooklyn/entity/database/PlaceholderTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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 brooklyn.entity.database;
-
-import org.testng.annotations.Test;
-
-public class PlaceholderTest {
-    @Test
-    public void noop() {}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/database/src/test/java/org/apache/brooklyn/entity/database/PlaceholderTest.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/test/java/org/apache/brooklyn/entity/database/PlaceholderTest.java b/sandbox/database/src/test/java/org/apache/brooklyn/entity/database/PlaceholderTest.java
new file mode 100644
index 0000000..564249d1
--- /dev/null
+++ b/sandbox/database/src/test/java/org/apache/brooklyn/entity/database/PlaceholderTest.java
@@ -0,0 +1,26 @@
+/*
+ * 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.entity.database;
+
+import org.testng.annotations.Test;
+
+public class PlaceholderTest {
+    @Test
+    public void noop() {}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
deleted file mode 100644
index af0845f..0000000
--- a/sandbox/extra/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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 brooklyn.entity.database.postgresql;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Effector;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EffectorStartableImpl;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.effector.EffectorBody;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.entity.salt.SaltConfig;
-import brooklyn.entity.salt.SaltConfigs;
-import brooklyn.entity.salt.SaltLifecycleEffectorTasks;
-import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.event.feed.ssh.SshFeed;
-import brooklyn.event.feed.ssh.SshPollConfig;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.task.DynamicTasks;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class PostgreSqlNodeSaltImpl extends EffectorStartableImpl implements PostgreSqlNode, SoftwareProcess {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PostgreSqlNodeSaltImpl.class);
-
-    public static final Effector<String> EXECUTE_SCRIPT = Effectors.effector(String.class, "executeScript")
-            .description("invokes a script")
-            .parameter(ExecuteScriptEffectorBody.SCRIPT)
-            .impl(new ExecuteScriptEffectorBody())
-            .build();
-
-    private SshFeed feed;
-
-    @Override
-    public void init() {
-        super.init();
-        new SaltPostgreSqlLifecycle().attachLifecycleEffectors(this);
-    }
-
-    public static class SaltPostgreSqlLifecycle extends SaltLifecycleEffectorTasks {
-        public SaltPostgreSqlLifecycle() {
-            usePidFile("/var/run/postgresql/*.pid");
-            useService("postgresql");
-        }
-
-        @Override
-        protected void startMinionAsync() {
-            Entities.warnOnIgnoringConfig(entity(), SaltConfig.SALT_FORMULAS);
-            Entities.warnOnIgnoringConfig(entity(), SaltConfig.SALT_RUN_LIST);
-            Entities.warnOnIgnoringConfig(entity(), SaltConfig.SALT_LAUNCH_ATTRIBUTES);
-
-            // TODO Set these as defaults, rather than replacing user's value!?
-            SaltConfigs.addToFormulas(entity(), "postgres", "https://github.com/saltstack-formulas/postgres-formula/archive/master.tar.gz");
-            SaltConfigs.addToRunList(entity(), "postgres");
-            SaltConfigs.addLaunchAttributes(entity(), ImmutableMap.<String,Object>builder()
-                    .put("port", DependentConfiguration.attributeWhenReady(entity(), PostgreSqlNode.POSTGRESQL_PORT))
-                    .put("listen_addresses", "*")
-                    .put("pg_hba.type", "host")
-                    .put("pg_hba.db", "all")
-                    .put("pg_hba.user", "all")
-                    .put("pg_hba.addr", "0.0.0.0/0")
-                    .put("pg_hba.method", "md5")
-                    .build());
-
-            super.startMinionAsync();
-        }
-
-        @Override
-        protected void postStartCustom() {
-            super.postStartCustom();
-
-            // now run the creation script
-            String creationScriptUrl = entity().getConfig(PostgreSqlNode.CREATION_SCRIPT_URL);
-            String creationScript;
-            if (creationScriptUrl != null) {
-                creationScript = new ResourceUtils(entity()).getResourceAsString(creationScriptUrl);
-            } else {
-                creationScript = entity().getConfig(PostgreSqlNode.CREATION_SCRIPT_CONTENTS);
-            }
-            entity().invoke(PostgreSqlNodeSaltImpl.EXECUTE_SCRIPT,
-                    ConfigBag.newInstance().configure(ExecuteScriptEffectorBody.SCRIPT, creationScript).getAllConfig()).getUnchecked();
-
-            // and finally connect sensors
-            ((PostgreSqlNodeSaltImpl) entity()).connectSensors();
-        }
-
-        @Override
-        protected void preStopCustom() {
-            ((PostgreSqlNodeSaltImpl) entity()).disconnectSensors();
-            super.preStopCustom();
-        }
-    }
-
-    public static class ExecuteScriptEffectorBody extends EffectorBody<String> {
-        public static final ConfigKey<String> SCRIPT = ConfigKeys.newStringConfigKey("script", "contents of script to run");
-
-        @Override
-        public String call(ConfigBag parameters) {
-            return DynamicTasks.queue(SshEffectorTasks.ssh(
-                    BashCommands.pipeTextTo(
-                            parameters.get(SCRIPT),
-                            BashCommands.sudoAsUser("postgres", "psql --file -")))
-                    .requiringExitCodeZero()).getStdout();
-        }
-    }
-
-    protected void connectSensors() {
-        setAttribute(DATASTORE_URL, String.format("postgresql://%s:%s/", getAttribute(HOSTNAME), getAttribute(POSTGRESQL_PORT)));
-
-        Location machine = Iterables.get(getLocations(), 0, null);
-
-        if (machine instanceof SshMachineLocation) {
-            feed = SshFeed.builder()
-                    .entity(this)
-                    .machine((SshMachineLocation)machine)
-                    .poll(new SshPollConfig<Boolean>(SERVICE_UP)
-                            .command("ps -ef | grep [p]ostgres")
-                            .setOnSuccess(true)
-                            .setOnFailureOrException(false))
-                    .build();
-        } else {
-            LOG.warn("Location(s) %s not an ssh-machine location, so not polling for status; setting serviceUp immediately", getLocations());
-        }
-    }
-
-    protected void disconnectSensors() {
-        if (feed != null) feed.stop();
-    }
-
-    @Override
-    public Integer getPostgreSqlPort() { return getAttribute(POSTGRESQL_PORT); }
-
-    @Override
-    public String getSharedMemory() { return getConfig(SHARED_MEMORY); }
-
-    @Override
-    public Integer getMaxConnections() { return getConfig(MAX_CONNECTIONS); }
-
-    @Override
-    public String getShortName() {
-        return "PostgreSQL";
-    }
-
-    @Override
-    public String executeScript(String commands) {
-        return Entities.invokeEffector(this, this, EXECUTE_SCRIPT,
-                ConfigBag.newInstance().configure(ExecuteScriptEffectorBody.SCRIPT, commands).getAllConfig()).getUnchecked();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltBashCommands.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltBashCommands.java b/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltBashCommands.java
deleted file mode 100644
index 70379f7..0000000
--- a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltBashCommands.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 brooklyn.entity.salt;
-
-import static brooklyn.util.ssh.BashCommands.downloadToStdout;
-
-import javax.annotation.Nullable;
-
-import org.apache.commons.io.FilenameUtils;
-
-import brooklyn.entity.chef.ChefBashCommands;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.io.Files;
-
-/**
- * BASH commands useful for setting up SaltStack.
- */
-@Beta
-public class SaltBashCommands {
-
-    /**
-     * SaltStack formulas can be found at {@code https://github.com/saltstack-formulas} as repositories.
-     * <p>
-     * This assumes the download is an archive containing a single directory on the root which will
-     * be renamed to {@code formulaName}. if that directory already has the correct name {@code formulaName}
-     * can be null, but if taking from a GitHub tarball it will typically be of the form {@code formulaName-master/}
-     * hence the renaming.
-     */
-    // TODO support installing from classpath, and using the repository (tie in with those methods)
-    public static final String downloadAndExpandFormula(String source, @Nullable String formulaName, boolean force) {
-        String dl = downloadAndExpandFormula(source);
-        if (formulaName==null) return dl;
-        String tmpName = "tmp-"+Strings.makeValidFilename(formulaName)+"-"+Identifiers.makeRandomId(4);
-        String installCmd = BashCommands.chain("mkdir "+tmpName, "cd "+tmpName, dl,
-                BashCommands.requireTest("`ls | wc -w` -eq 1", "The archive must contain exactly one directory"),
-                "FORMULA_EXPANDED_DIR=`ls`",
-                "mv $FORMULA_EXPANDED_DIR '../"+formulaName+"'",
-                "cd ..",
-                "rm -rf "+tmpName);
-        if (!force) return BashCommands.alternatives("ls "+formulaName, installCmd);
-        else return BashCommands.alternatives("rm -rf "+formulaName, installCmd);
-    }
-
-    /**
-     * Same as {@link #downloadAndExpandFormula(String, String)} with no formula name.
-     * <p>
-     * Equivalent to the following command, but substituting the given {@code sourceUrl}.
-     * <pre>{@code
-     * curl -f -L  https://github.com/saltstack-formulas/nginx-formula/archive/master.tar.gz | tar xvz
-     * }</pre>
-     */
-    public static final String downloadAndExpandFormula(String sourceUrl) {
-        String ext = Files.getFileExtension(sourceUrl);
-        if ("tar".equalsIgnoreCase(ext))
-            return downloadToStdout(sourceUrl) + " | tar xv";
-        if ("tgz".equalsIgnoreCase(ext) || sourceUrl.toLowerCase().endsWith(".tar.gz"))
-            return downloadToStdout(sourceUrl) + " | tar xvz";
-
-        String target = FilenameUtils.getName(sourceUrl);
-        if (target==null) target = ""; else target = target.trim();
-        target += "_"+Strings.makeRandomId(4);
-
-        if ("zip".equalsIgnoreCase(ext) || "tar.gz".equalsIgnoreCase(ext))
-            return BashCommands.chain(
-                BashCommands.commandToDownloadUrlAs(sourceUrl, target),
-                "unzip "+target,
-                "rm "+target);
-
-        throw new UnsupportedOperationException("No way to expand "+sourceUrl+" (yet)");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltConfig.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltConfig.java b/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltConfig.java
deleted file mode 100644
index b14ba98..0000000
--- a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltConfig.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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 brooklyn.entity.salt;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.MapConfigKey;
-import brooklyn.event.basic.SetConfigKey;
-import brooklyn.management.TaskAdaptable;
-import brooklyn.management.TaskFactory;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.reflect.TypeToken;
-
-/**
- * {@link ConfigKey}s used to configure Salt entities.
- *
- * @see SaltConfigs
- * @see SaltLifecycleEffectorTasks
- */
-@Beta
-public interface SaltConfig {
-
-    MapConfigKey<String> SALT_FORMULAS = new MapConfigKey<String>(String.class,
-            "salt.formulaUrls", "Map of Salt formula URLs (normally GutHub repository archives from the salt-formulas user)");
-    SetConfigKey<String> SALT_RUN_LIST = new SetConfigKey<String>(String.class,
-            "salt.runList", "Set of Salt states to install from the formula URLs");
-    MapConfigKey<Object> SALT_LAUNCH_ATTRIBUTES = new MapConfigKey<Object>(Object.class, "salt.launch.attributes", "TODO");
-
-    @SetFromFlag("master")
-    ConfigKey<SaltStackMaster> MASTER = ConfigKeys.newConfigKey(SaltStackMaster.class,
-            "salt.master.entity", "The Salt master server");
-
-    AttributeSensor<String> MINION_ID = new BasicAttributeSensor<String>(String.class,
-            "salt.minionId", "The ID for a Salt minion");
-
-    @SetFromFlag("masterless")
-    ConfigKey<Boolean> MASTERLESS_MODE = ConfigKeys.newBooleanConfigKey(
-            "salt.masterless", "Salt masterless, minion only configuration (default uses master and minion)",
-            Boolean.FALSE);
-
-    @SetFromFlag("masterConfigUrl")
-    ConfigKey<String> MASTER_CONFIGURATION_URL = ConfigKeys.newStringConfigKey(
-            "salt.master.templateUrl", "The Salt master configuration file template URL",
-            "classpath://brooklyn/entity/salt/master");
-
-    @SetFromFlag("minionConfigUrl")
-    ConfigKey<String> MINION_CONFIGURATION_URL = ConfigKeys.newStringConfigKey(
-            "salt.minion.templateUrl", "The Salt minion configuration file template URL",
-            "classpath://brooklyn/entity/salt/minion");
-
-    @SetFromFlag("masterlessConfigUrl")
-    ConfigKey<String> MASTERLESS_CONFIGURATION_URL = ConfigKeys.newStringConfigKey(
-            "salt.masterless.templateUrl", "The Salt minion masterless configuration file template URL",
-            "classpath://brooklyn/entity/salt/masterless");
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @SetFromFlag("minionIdFunction")
-    ConfigKey<Function<Entity, String>> MINION_ID_FUNCTION = new BasicConfigKey(Function.class,
-            "salt.minionId.function", "Function to generate the ID of a Salt minion for an entity", Functions.toStringFunction());
-
-    @SuppressWarnings("serial")
-    ConfigKey<TaskFactory<? extends TaskAdaptable<Boolean>>> IS_RUNNING_TASK = ConfigKeys.newConfigKey(
-            new TypeToken<TaskFactory<? extends TaskAdaptable<Boolean>>>() {}, 
-            "salt.driver.isRunningTask");
-
-    @SuppressWarnings("serial")
-    ConfigKey<TaskFactory<?>> STOP_TASK = ConfigKeys.newConfigKey(
-            new TypeToken<TaskFactory<?>>() {}, 
-            "salt.driver.stopTask");
-
-    /**
-     * The {@link SaltStackMaster master} entity.
-     */
-    SaltStackMaster getMaster();
-
-}