You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/12 17:55:44 UTC

[26/35] incubator-brooklyn git commit: [BROOKLYN-162] package rename to org.apache.brooklyn: software/webapp

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
deleted file mode 100644
index c712b6a..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
+++ /dev/null
@@ -1,459 +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.dns.geoscaling;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.tidy.Tidy;
-
-import brooklyn.util.http.HttpTool;
-import brooklyn.util.text.Strings;
-
-/**
- * For interacting with the www.geoscaling.com DNS service.
- * 
- * If you get the SSL error "peer not authenticated", then it means the required certificate is
- * not in your trust store. For example, see:
- * {@linkplain http://stackoverflow.com/questions/373295/digital-certificate-how-to-import-cer-file-in-to-truststore-file-using}. 
- * The chain of certificates (as of October 2014, found by viewing in Chrome) is:
- * <ol>
- *   <li> AddTrust External CA root
- *   <li> COMODO RSA Certification Authority
- *   <li> COMODO RSA Domain Validation Secure Server CA
- *   <li> www.geoscaling.com
- * </ol>
- */
-public class GeoscalingWebClient {
-    public static final Logger log = LoggerFactory.getLogger(GeoscalingWebClient.class);
-    
-    public static final long PROVIDE_NETWORK_INFO = 1 << 0;
-    public static final long PROVIDE_CITY_INFO    = 1 << 1;
-    public static final long PROVIDE_COUNTRY_INFO = 1 << 2;
-    public static final long PROVIDE_EXTRA_INFO   = 1 << 3;
-    public static final long PROVIDE_UPTIME_INFO  = 1 << 4;
-    
-    private static final String HOST ="www.geoscaling.com";
-    private static final String PATH ="dns2/index.php";
-    private HttpClient httpClient;
-    private Tidy tidy;
-    private List<Domain> primaryDomains = null;
-    
-    
-    public class Domain {
-        public final int id;
-        public final String name;
-        private List<SmartSubdomain> smartSubdomains = null;
-        
-        public Domain(int id, String name) {
-            this.id = id;
-            this.name = name.toLowerCase();
-        }
-        
-        public List<SmartSubdomain> getSmartSubdomains() {
-            if (smartSubdomains == null)
-                smartSubdomains = GeoscalingWebClient.this.fetchSmartSubdomains(this);
-            return smartSubdomains;
-        }
-        
-        public SmartSubdomain getSmartSubdomain(String name) {
-            name = name.toLowerCase();
-            for (SmartSubdomain s : getSmartSubdomains()) {
-                if (s.name.equals(name)) return s;
-            }
-            return null;
-        }
-        
-        /** e.g. editRecord("foo", "A", "1.2.3.4"), which assuming this domain is "bar.com", will create A record for foo.bar.com.
-         * <p>
-         * or editRecord("*.foo", "CNAME", "foo.bar.com") to map everything at *.foo.bar.com to foo.bar.com
-         */
-        public void editRecord(String subdomainPart, String type, String content) {
-            subdomainPart = Strings.removeFromEnd(subdomainPart, "."+name);
-            editSubdomainRecord(id, subdomainPart, type, content);
-        }
-        
-        public SmartSubdomain getSmartSubdomain(int id) {
-            for (SmartSubdomain s : getSmartSubdomains()) {
-                if (s.id == id) return s;
-            }
-            return null;
-        }
-        
-        public void createSmartSubdomain(String name) {
-            GeoscalingWebClient.this.createSmartSubdomain(id, name);
-            smartSubdomains = fetchSmartSubdomains(this);
-        }
-        
-        public void delete() {
-            deletePrimaryDomain(id);
-            primaryDomains = fetchPrimaryDomains();
-        }
-        
-        @Override
-        public String toString() {
-            return "Domain["+name+" ("+id+")]";
-        }
-        
-        @Override
-        public int hashCode() {
-            return id;
-        }
-    }
-    
-    
-    public class SmartSubdomain {
-        public final Domain parent;
-        public final int id;
-        public String name;
-        
-        public SmartSubdomain(Domain parent, int id, String name) {
-            this.parent = parent;
-            this.id = id;
-            this.name = name.toLowerCase();
-        }
-        
-        public void configure(long flags, String phpScript) {
-            configureSmartSubdomain(parent.id, id, name, flags, phpScript);
-        }
-        
-        public void delete() {
-            deleteSmartSubdomain(parent.id, id);
-            parent.smartSubdomains = fetchSmartSubdomains(parent);
-        }
-        
-        @Override
-        public String toString() {
-            return "SmartSubdomain["+name+" ("+id+")]";
-        }
-        
-        @Override
-        public int hashCode() {
-            return id;
-        }
-    }
-    
-    
-    public GeoscalingWebClient() {
-        this(HttpTool.httpClientBuilder().build());
-    }
-
-    public GeoscalingWebClient(HttpClient httpClient) {
-        this.httpClient = httpClient;
-        this.tidy = new Tidy();
-        // Silently swallow all HTML errors/warnings.
-        tidy.setErrout(new PrintWriter(new OutputStream() {
-            @Override public void write(int b) throws IOException { }
-        }));
-    }
-    
-    public GeoscalingWebClient(String username, String password) {
-        this();
-        login(username, password);
-    }
-    
-    public void login(String username, String password) {
-        try {
-            String url = MessageFormat.format("https://{0}/{1}?module=auth", HOST, PATH);
-            
-            HttpPost request = new HttpPost(url);
-            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
-            nameValuePairs.add(new BasicNameValuePair("username", username));
-            nameValuePairs.add(new BasicNameValuePair("password", password));
-            request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-            
-            sendRequest(request, true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to log-in to GeoScaling service: "+e, e);
-        }
-    }
-    
-    public void logout() {
-        try {
-            String url = MessageFormat.format("https://{0}/{1}?module=auth&logout", HOST, PATH);
-            sendRequest(new HttpGet(url), true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to log-out of GeoScaling service: "+e, e);
-        }
-    }
-    
-    public List<Domain> getPrimaryDomains() {
-        if (primaryDomains == null)
-            primaryDomains = fetchPrimaryDomains();
-        return primaryDomains;
-    }
-    
-    public Domain getPrimaryDomain(String name) {
-        name = name.toLowerCase();
-        for (Domain d : getPrimaryDomains()) {
-            if (d.name.equals(name)) return d;
-        }
-        return null;
-    }
-    
-    public Domain getPrimaryDomain(int id) {
-        for (Domain d : getPrimaryDomains()) {
-            if (d.id == id) return d;
-        }
-        return null;
-    }
-    
-    public void createPrimaryDomain(String name) {
-        try {
-            name = name.toLowerCase();
-            String url = MessageFormat.format("https://{0}/{1}?module=domains", HOST, PATH);
-            
-            HttpPost request = new HttpPost(url);
-            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
-            nameValuePairs.add(new BasicNameValuePair("MAX_FILE_SIZE", "65536"));
-            nameValuePairs.add(new BasicNameValuePair("domain", FilenameUtils.removeExtension(name)));
-            nameValuePairs.add(new BasicNameValuePair("tld", FilenameUtils.getExtension(name)));
-            request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-            
-            sendRequest(request, true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to create GeoScaling smart subdomain: "+e, e);
-        }
-        
-        primaryDomains = fetchPrimaryDomains();
-    }
-    
-    private List<Domain> fetchPrimaryDomains() {
-        try {
-            List<Domain> domains = new LinkedList<Domain>();
-            String url = MessageFormat.format("https://{0}/{1}?module=domains", HOST, PATH);
-            HttpResponse response = sendRequest(new HttpGet(url), false);
-            HttpEntity entity = response.getEntity();
-            if (entity != null) {
-                Document document = tidy.parseDOM(entity.getContent(), null);
-                NodeList links = document.getElementsByTagName("a");
-                for (int i = 0; i < links.getLength(); ++i) {
-                    Element link = (Element) links.item(i);
-                    String href = link.getAttribute("href");
-                    Pattern p = Pattern.compile("module=domain.*&id=(\\d+)");
-                    Matcher m = p.matcher(href);
-                    if (!m.find(0)) continue;
-                    
-                    int id = Integer.parseInt(m.group(1));
-                    String name = getTextContent(link).trim();
-                    if (name.length() == 0) continue;
-                    
-                    domains.add(new Domain(id, name));
-                }
-                
-                EntityUtils.consume(entity);
-            }
-            
-            return domains;
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to retrieve GeoScaling subdomains: "+e, e);
-        }
-    }
-    
-    private void deletePrimaryDomain(int primaryDomainId) {
-        try {
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?module=domain&id={2,number,#}&delete=1",
-                    HOST, PATH, primaryDomainId);
-            
-            sendRequest(new HttpGet(url), true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to delete GeoScaling primary domain: "+e, e);
-        }
-    }
-    
-    private List<SmartSubdomain> fetchSmartSubdomains(Domain parent) {
-        try {
-            List<SmartSubdomain> subdomains = new LinkedList<SmartSubdomain>();
-            
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?module=smart_subdomains&id={2,number,#}",
-                    HOST, PATH, parent.id);
-            
-            HttpResponse response = sendRequest(new HttpGet(url), false);
-            HttpEntity entity = response.getEntity();
-            if (entity != null) {
-                Document document = tidy.parseDOM(entity.getContent(), null);
-                NodeList links = document.getElementsByTagName("a");
-                for (int i = 0; i < links.getLength(); ++i) {
-                    Element link = (Element) links.item(i);
-                    String href = link.getAttribute("href");
-                    Pattern p = Pattern.compile("module=smart_subdomain.*&subdomain_id=(\\d+)");
-                    Matcher m = p.matcher(href);
-                    if (!m.find(0)) continue;
-                    
-                    int subdomainId = Integer.parseInt(m.group(1));
-                    String name = getTextContent(link);
-                    if (name.trim().length() == 0) continue;
-                    
-                    name = name.substring(0, name.length() - parent.name.length() - 1);
-                    subdomains.add(new SmartSubdomain(parent, subdomainId, name));
-                }
-                
-                EntityUtils.consume(entity);
-            }
-            
-            return subdomains;
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to retrieve GeoScaling smart subdomains: "+e, e);
-        }
-    }
-    
-    private void createSmartSubdomain(int primaryDomainId, String smartSubdomainName) {
-        try {
-            smartSubdomainName = smartSubdomainName.toLowerCase();
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?module=smart_subdomains&id={2,number,#}",
-                    HOST, PATH, primaryDomainId);
-            
-            HttpPost request = new HttpPost(url);
-            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
-            nameValuePairs.add(new BasicNameValuePair("MAX_FILE_SIZE", "65536"));
-            nameValuePairs.add(new BasicNameValuePair("smart_subdomain_name", smartSubdomainName));
-            request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-                        
-            sendRequest(request, true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to create GeoScaling smart subdomain: "+e, e);
-        }
-    }
-    
-    private void deleteSmartSubdomain(int primaryDomainId, int smartSubdomainId) {
-        try {
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?module=smart_subdomains&id={2,number,#}&delete={3,number,#}",
-                    HOST, PATH, primaryDomainId, smartSubdomainId);
-            
-            sendRequest(new HttpGet(url), true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to delete GeoScaling smart subdomain: "+e, e);
-        }
-    }
-    
-    private void configureSmartSubdomain(int primaryDomainId, int smartSubdomainId, String smartSubdomainName,
-            long flags, String phpScript) {
-        
-        try {
-            smartSubdomainName = smartSubdomainName.toLowerCase();
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?module=smart_subdomain&id={2,number,#}&subdomain_id={3,number,#}",
-                    HOST, PATH, primaryDomainId, smartSubdomainId);
-            
-            HttpPost request = new HttpPost(url);
-            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
-            nameValuePairs.add(new BasicNameValuePair("MAX_FILE_SIZE", "65536"));
-            nameValuePairs.add(new BasicNameValuePair("name", smartSubdomainName));
-            if ((flags & PROVIDE_NETWORK_INFO) != 0) nameValuePairs.add(new BasicNameValuePair("share_as_info", "on"));
-            if ((flags & PROVIDE_CITY_INFO) != 0) nameValuePairs.add(new BasicNameValuePair("share_city_info", "on"));
-            if ((flags & PROVIDE_COUNTRY_INFO) != 0) nameValuePairs.add(new BasicNameValuePair("share_country_info", "on"));
-            if ((flags & PROVIDE_EXTRA_INFO) != 0) nameValuePairs.add(new BasicNameValuePair("share_extra_info", "on"));
-            if ((flags & PROVIDE_UPTIME_INFO) != 0) nameValuePairs.add(new BasicNameValuePair("share_uptime_info", "on"));
-            nameValuePairs.add(new BasicNameValuePair("code", phpScript));
-            request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-            
-            sendRequest(request, true);
-            
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to update GeoScaling smart subdomain: "+e, e);
-        }
-    }
-
-    private void editSubdomainRecord(int primaryDomainId, String record, String type, String content) {
-        
-        try {
-            String url = MessageFormat.format(
-                    "https://{0}/{1}?",
-                    HOST, "dns2/ajax/add_record.php");
-
-            HttpPost request = new HttpPost(url);
-            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
-            nameValuePairs.add(new BasicNameValuePair("id", ""+primaryDomainId));
-            nameValuePairs.add(new BasicNameValuePair("name", record));
-            nameValuePairs.add(new BasicNameValuePair("type", type));
-            nameValuePairs.add(new BasicNameValuePair("content", content));
-            nameValuePairs.add(new BasicNameValuePair("ttl", "300"));
-            nameValuePairs.add(new BasicNameValuePair("prio", "0"));
-           
-            request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-            
-            sendRequest(request, true);
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to update GeoScaling smart subdomain: "+e, e);
-        }
-    }
-    
-
-    protected HttpResponse sendRequest(HttpUriRequest request, boolean consumeResponse) throws ClientProtocolException, IOException {
-        if (log.isDebugEnabled()) log.debug("Geoscaling request: "+
-                request.getURI()+
-                (request instanceof HttpPost ? " "+((HttpPost)request).getEntity() : ""));
-        HttpResponse response = httpClient.execute(request);
-        if (log.isDebugEnabled()) log.debug("Geoscaling response: "+response);
-        if (consumeResponse)
-            EntityUtils.consume(response.getEntity());
-        return response;
-    }
-
-    private static String getTextContent(Node n) {
-        StringBuffer sb = new StringBuffer();
-        NodeList childNodes = n.getChildNodes();
-        for (int i = 0; i < childNodes.getLength(); ++i) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.TEXT_NODE)
-                sb.append(child.getNodeValue());
-            else
-                sb.append(getTextContent(child));
-        }
-        return sb.toString();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractController.java b/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractController.java
deleted file mode 100644
index e2ba3a1..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractController.java
+++ /dev/null
@@ -1,74 +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.proxy;
-
-import java.util.Set;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.group.Cluster;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
-import brooklyn.util.flags.SetFromFlag;
-
-/**
- * Represents a controller mechanism for a {@link Cluster}.
- */
-@ImplementedBy(AbstractControllerImpl.class)
-public interface AbstractController extends SoftwareProcess, LoadBalancer {
-
-    @SetFromFlag("domain")
-    BasicAttributeSensorAndConfigKey<String> DOMAIN_NAME = new BasicAttributeSensorAndConfigKey<String>(
-            String.class, "proxy.domainName", "Domain name that this controller responds to, or null if it responds to all domains", null);
-
-    @SetFromFlag("ssl")
-    ConfigKey<ProxySslConfig> SSL_CONFIG = ConfigKeys.newConfigKey(ProxySslConfig.class,
-            "proxy.ssl.config", "Configuration (e.g. certificates) for SSL; causes server to run with HTTPS instead of HTTP");
-    
-
-    @SetFromFlag("serviceUpUrlPath")
-    ConfigKey<String> SERVICE_UP_URL_PATH = ConfigKeys.newStringConfigKey(
-            "controller.config.serviceUpUrlPath", "The path that will be appended to the root URL to determine SERVICE_UP", "");
-
-    boolean isActive();
-
-    ProxySslConfig getSslConfig();
-
-    boolean isSsl();
-
-    String getProtocol();
-
-    /** returns primary domain this controller responds to, or null if it responds to all domains */
-    String getDomain();
-
-    Integer getPort();
-
-    /** primary URL this controller serves, if one can / has been inferred */
-    String getUrl();
-
-    AttributeSensor<Integer> getPortNumberSensor();
-
-    AttributeSensor<String> getHostnameSensor();
-
-    AttributeSensor<String> getHostAndPortSensor();
-    
-    Set<String> getServerPoolAddresses();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractControllerImpl.java
deleted file mode 100644
index feff6ef..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractControllerImpl.java
+++ /dev/null
@@ -1,516 +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.proxy;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.management.Task;
-import org.apache.brooklyn.policy.Policy;
-import org.apache.brooklyn.policy.PolicySpec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.Group;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.basic.SoftwareProcessImpl;
-import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.entity.group.Cluster;
-import brooklyn.entity.trait.Startable;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.Machines;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.net.HostAndPort;
-
-/**
- * Represents a controller mechanism for a {@link Cluster}.
- */
-public abstract class AbstractControllerImpl extends SoftwareProcessImpl implements AbstractController {
-    
-    // TODO Should review synchronization model. Currently, all changes to the serverPoolTargets
-    // (and checking for potential changes) is done while synchronized on serverPoolAddresses. That means it 
-    // will also call update/reload while holding the lock. This is "conservative", but means
-    // sub-classes need to be extremely careful about any additional synchronization and of
-    // their implementations of update/reconfigureService/reload.
-    
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractControllerImpl.class);
-
-    protected volatile boolean isActive;
-    protected volatile boolean updateNeeded = true;
-
-    protected AbstractMembershipTrackingPolicy serverPoolMemberTrackerPolicy;
-    // final because this is the synch target
-    final protected Set<String> serverPoolAddresses = Sets.newLinkedHashSet();
-    protected Map<Entity,String> serverPoolTargets = Maps.newLinkedHashMap();
-    
-    public AbstractControllerImpl() {
-        this(MutableMap.of(), null, null);
-    }
-    public AbstractControllerImpl(Map<?, ?> properties) {
-        this(properties, null, null);
-    }
-    public AbstractControllerImpl(Entity parent) {
-        this(MutableMap.of(), parent, null);
-    }
-    public AbstractControllerImpl(Map<?, ?> properties, Entity parent) {
-        this(properties, parent, null);
-    }
-    public AbstractControllerImpl(Entity parent, Cluster cluster) {
-        this(MutableMap.of(), parent, cluster);
-    }
-    public AbstractControllerImpl(Map<?, ?> properties, Entity parent, Cluster cluster) {
-        super(properties, parent);
-    }
-
-    @Override
-    public void init() {
-        super.init();
-        setAttribute(SERVER_POOL_TARGETS, ImmutableMap.<Entity, String>of());
-    }
-    
-    protected void addServerPoolMemberTrackingPolicy() {
-        Group serverPool = getServerPool();
-        if (serverPool == null) {
-            return; // no-op
-        }
-        if (serverPoolMemberTrackerPolicy != null) {
-            LOG.debug("Call to addServerPoolMemberTrackingPolicy when serverPoolMemberTrackingPolicy already exists, removing and re-adding, in {}", this);
-            removeServerPoolMemberTrackingPolicy();
-        }
-        for (Policy p: getPolicies()) {
-            if (p instanceof ServerPoolMemberTrackerPolicy) {
-                // TODO want a more elegant idiom for this!
-                LOG.info(this+" picking up "+p+" as the tracker (already set, often due to rebind)");
-                serverPoolMemberTrackerPolicy = (ServerPoolMemberTrackerPolicy) p;
-                return;
-            }
-        }
-        
-        AttributeSensor<?> hostAndPortSensor = getConfig(HOST_AND_PORT_SENSOR);
-        AttributeSensor<?> hostnameSensor = getConfig(HOSTNAME_SENSOR);
-        AttributeSensor<?> portSensor = getConfig(PORT_NUMBER_SENSOR);
-        Set<AttributeSensor<?>> sensorsToTrack;
-        if (hostAndPortSensor != null) {
-            sensorsToTrack = ImmutableSet.<AttributeSensor<?>>of(hostAndPortSensor);
-        } else {
-            sensorsToTrack = ImmutableSet.<AttributeSensor<?>>of(hostnameSensor, portSensor);
-        }
-        
-        serverPoolMemberTrackerPolicy = addPolicy(PolicySpec.create(ServerPoolMemberTrackerPolicy.class)
-                .displayName("Controller targets tracker")
-                .configure("group", serverPool)
-                .configure("sensorsToTrack", sensorsToTrack));
-
-        LOG.info("Added policy {} to {}", serverPoolMemberTrackerPolicy, this);
-        
-        // Initialize ourselves immediately with the latest set of members; don't wait for
-        // listener notifications because then will be out-of-date for short period (causing 
-        // problems for rebind)
-        Map<Entity,String> serverPoolTargets = Maps.newLinkedHashMap();
-        for (Entity member : getServerPool().getMembers()) {
-            if (belongsInServerPool(member)) {
-                if (LOG.isTraceEnabled()) LOG.trace("Done {} checkEntity {}", this, member);
-                String address = getAddressOfEntity(member);
-                serverPoolTargets.put(member, address);
-            }
-        }
-
-        LOG.info("Resetting {}, server pool targets {}", new Object[] {this, serverPoolTargets});
-        setAttribute(SERVER_POOL_TARGETS, serverPoolTargets);
-    }
-    
-    protected void removeServerPoolMemberTrackingPolicy() {
-        if (serverPoolMemberTrackerPolicy != null) {
-            removePolicy(serverPoolMemberTrackerPolicy);
-        }
-    }
-    
-    public static class ServerPoolMemberTrackerPolicy extends AbstractMembershipTrackingPolicy {
-        @Override
-        protected void onEntityEvent(EventType type, Entity entity) {
-            // relies on policy-rebind injecting the implementation rather than the dynamic-proxy
-            ((AbstractControllerImpl)super.entity).onServerPoolMemberChanged(entity);
-        }
-    }
-    
-    @Override
-    public Set<String> getServerPoolAddresses() {
-        return ImmutableSet.copyOf(Iterables.filter(getAttribute(SERVER_POOL_TARGETS).values(), Predicates.notNull()));
-    }
-
-    /**
-     * Opportunity to do late-binding of the cluster that is being controlled. Must be called before start().
-     * Can pass in the 'serverPool'.
-     */
-    @Override
-    public void bind(Map<?,?> flags) {
-        if (flags.containsKey("serverPool")) {
-            setConfigEvenIfOwned(SERVER_POOL, (Group) flags.get("serverPool"));
-        } 
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void onManagementNoLongerMaster() {
-        super.onManagementNoLongerMaster(); // TODO remove when deprecated method in parent removed
-        isActive = false;
-        removeServerPoolMemberTrackingPolicy();
-    }
-
-    private Group getServerPool() {
-        return getConfig(SERVER_POOL);
-    }
-    
-    @Override
-    public boolean isActive() {
-        return isActive;
-    }
-    
-    @Override
-    public boolean isSsl() {
-        return getSslConfig() != null;
-    }
-    
-    @Override
-    public ProxySslConfig getSslConfig() {
-        return getConfig(SSL_CONFIG);
-    }
-    
-    @Override
-    public String getProtocol() {
-        return getAttribute(PROTOCOL);
-    }
-
-    /** returns primary domain this controller responds to, or null if it responds to all domains */
-    @Override
-    public String getDomain() {
-        return getAttribute(DOMAIN_NAME);
-    }
-    
-    @Override
-    public Integer getPort() {
-        if (isSsl())
-            return getAttribute(PROXY_HTTPS_PORT);
-        else
-            return getAttribute(PROXY_HTTP_PORT);
-    }
-
-    /** primary URL this controller serves, if one can / has been inferred */
-    @Override
-    public String getUrl() {
-        return Strings.toString( getAttribute(MAIN_URI) );
-    }
-
-    @Override
-    public AttributeSensor<Integer> getPortNumberSensor() {
-        return getAttribute(PORT_NUMBER_SENSOR);
-    }
-
-    @Override
-    public AttributeSensor<String> getHostnameSensor() {
-        return getAttribute(HOSTNAME_SENSOR);
-    }
-
-    @Override
-    public AttributeSensor<String> getHostAndPortSensor() {
-        return getAttribute(HOST_AND_PORT_SENSOR);
-    }
-    
-    @Override
-    public abstract void reload();
-
-    protected String inferProtocol() {
-        return isSsl() ? "https" : "http";
-    }
-    
-    /** returns URL, if it can be inferred; null otherwise */
-    protected String inferUrl(boolean requireManagementAccessible) {
-        String protocol = checkNotNull(getProtocol(), "no protocol configured");
-        String domain = getDomain();
-        if (domain != null && domain.startsWith("*.")) {
-            domain = domain.replace("*.", ""); // Strip wildcard
-        }
-        Integer port = checkNotNull(getPort(), "no port configured (the requested port may be in use)");
-        if (requireManagementAccessible) {
-            HostAndPort accessible = BrooklynAccessUtils.getBrooklynAccessibleAddress(this, port);
-            if (accessible!=null) {
-                domain = accessible.getHostText();
-                port = accessible.getPort();
-            }
-        }
-        if (domain==null) domain = Machines.findSubnetHostname(this).orNull();
-        if (domain==null) return null;
-        return protocol+"://"+domain+":"+port+"/"+getConfig(SERVICE_UP_URL_PATH);
-    }
-
-    protected String inferUrl() {
-        return inferUrl(false);
-    }
-
-    @Override
-    protected Collection<Integer> getRequiredOpenPorts() {
-        Collection<Integer> result = super.getRequiredOpenPorts();
-        if (groovyTruth(getAttribute(PROXY_HTTP_PORT))) result.add(getAttribute(PROXY_HTTP_PORT));
-        if (groovyTruth(getAttribute(PROXY_HTTPS_PORT))) result.add(getAttribute(PROXY_HTTPS_PORT));
-        return result;
-    }
-
-    @Override
-    protected void preStart() {
-        super.preStart();
-        computePortsAndUrls();
-    }
-    
-    protected void computePortsAndUrls() {
-        AttributeSensor<String> hostAndPortSensor = getConfig(HOST_AND_PORT_SENSOR);
-        Maybe<Object> hostnameSensor = config().getRaw(HOSTNAME_SENSOR);
-        Maybe<Object> portSensor = config().getRaw(PORT_NUMBER_SENSOR);
-        if (hostAndPortSensor != null) {
-            checkState(!hostnameSensor.isPresent() && !portSensor.isPresent(), 
-                    "Must not set %s and either of %s or %s", HOST_AND_PORT_SENSOR, HOSTNAME_SENSOR, PORT_NUMBER_SENSOR);
-        }
-
-        ConfigToAttributes.apply(this);
-
-        setAttribute(PROTOCOL, inferProtocol());
-        setAttribute(MAIN_URI, URI.create(inferUrl()));
-        setAttribute(ROOT_URL, inferUrl());
- 
-        checkNotNull(getPortNumberSensor(), "no sensor configured to infer port number");
-    }
-    
-    @Override
-    protected void connectSensors() {
-        super.connectSensors();
-        // TODO when rebind policies, and rebind calls connectSensors, then this will cause problems.
-        // Also relying on addServerPoolMemberTrackingPolicy to set the serverPoolAddresses and serverPoolTargets.
-
-        addServerPoolMemberTrackingPolicy();
-    }
-    
-    @Override
-    protected void postStart() {
-        super.postStart();
-        isActive = true;
-        update();
-    }
-
-    @Override
-    protected void postRebind() {
-        super.postRebind();
-        Lifecycle state = getAttribute(SERVICE_STATE_ACTUAL);
-        if (state != null && state == Lifecycle.RUNNING) {
-            isActive = true;
-            updateNeeded();
-        }
-    }
-
-    @Override
-    protected void preStop() {
-        super.preStop();
-        removeServerPoolMemberTrackingPolicy();
-    }
-
-    /** 
-     * Implementations should update the configuration so that 'serverPoolAddresses' are targeted.
-     * The caller will subsequently call reload to apply the new configuration.
-     */
-    protected abstract void reconfigureService();
-    
-    public void updateNeeded() {
-        synchronized (serverPoolAddresses) {
-            if (updateNeeded) return;
-            updateNeeded = true;
-            LOG.debug("queueing an update-needed task for "+this+"; update will occur shortly");
-            Entities.submit(this, Tasks.builder().name("update-needed").body(new Runnable() {
-                @Override
-                public void run() {
-                    if (updateNeeded)
-                        AbstractControllerImpl.this.update();
-                } 
-            }).build());
-        }
-    }
-    
-    @Override
-    public void update() {
-        try {
-            Task<?> task = updateAsync();
-            if (task != null) task.getUnchecked();
-            ServiceStateLogic.ServiceProblemsLogic.clearProblemsIndicator(this, "update");
-        } catch (Exception e) {
-            ServiceStateLogic.ServiceProblemsLogic.updateProblemsIndicator(this, "update", "update failed with: "+Exceptions.collapseText(e));
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    public Task<?> updateAsync() {
-        synchronized (serverPoolAddresses) {
-            Task<?> result = null;
-            if (!isActive()) updateNeeded = true;
-            else {
-                updateNeeded = false;
-                LOG.debug("Updating {} in response to changes", this);
-                LOG.info("Updating {}, server pool targets {}", new Object[] {this, getAttribute(SERVER_POOL_TARGETS)});
-                reconfigureService();
-                LOG.debug("Reloading {} in response to changes", this);
-                // reload should happen synchronously
-                result = invoke(RELOAD);
-            }
-            return result;
-        }
-    }
-
-    protected void onServerPoolMemberChanged(Entity member) {
-        synchronized (serverPoolAddresses) {
-            if (LOG.isTraceEnabled()) LOG.trace("For {}, considering membership of {} which is in locations {}", 
-                new Object[] {this, member, member.getLocations()});
-            if (belongsInServerPool(member)) {
-                addServerPoolMember(member);
-            } else {
-                removeServerPoolMember(member);
-            }
-            if (LOG.isTraceEnabled()) LOG.trace("Done {} checkEntity {}", this, member);
-        }
-    }
-    
-    protected boolean belongsInServerPool(Entity member) {
-        if (!groovyTruth(member.getAttribute(Startable.SERVICE_UP))) {
-            if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, eliminating because not up", this, member);
-            return false;
-        }
-        if (!getServerPool().getMembers().contains(member)) {
-            if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, eliminating because not member", this, member);
-            return false;
-        }
-        if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, approving", this, member);
-        return true;
-    }
-    
-    protected void addServerPoolMember(Entity member) {
-        synchronized (serverPoolAddresses) {
-            String oldAddress = getAttribute(SERVER_POOL_TARGETS).get(member);
-            String newAddress = getAddressOfEntity(member);
-            if (Objects.equal(newAddress, oldAddress)) {
-                if (LOG.isTraceEnabled())
-                    if (LOG.isTraceEnabled()) LOG.trace("Ignoring unchanged address {}", oldAddress);
-                return;
-            } else if (newAddress == null) {
-                LOG.info("Removing from {}, member {} with old address {}, because inferred address is now null", new Object[] {this, member, oldAddress});
-            } else {
-                if (oldAddress != null) {
-                    LOG.info("Replacing in {}, member {} with old address {}, new address {}", new Object[] {this, member, oldAddress, newAddress});
-                } else {
-                    LOG.info("Adding to {}, new member {} with address {}", new Object[] {this, member, newAddress});
-                }
-            }
-
-            if (Objects.equal(oldAddress, newAddress)) {
-                if (LOG.isTraceEnabled()) LOG.trace("For {}, ignoring change in member {} because address still {}", new Object[] {this, member, newAddress});
-                return;
-            }
-
-            // TODO this does it synchronously; an async method leaning on `updateNeeded` and `update` might
-            // be more appropriate, especially when this is used in a listener
-            MapAttribute.put(this, SERVER_POOL_TARGETS, member, newAddress);
-            updateAsync();
-        }
-    }
-    
-    protected void removeServerPoolMember(Entity member) {
-        synchronized (serverPoolAddresses) {
-            if (!getAttribute(SERVER_POOL_TARGETS).containsKey(member)) {
-                if (LOG.isTraceEnabled()) LOG.trace("For {}, not removing as don't have member {}", new Object[] {this, member});
-                return;
-            }
-
-            String address = MapAttribute.remove(this, SERVER_POOL_TARGETS, member);
-
-            LOG.info("Removing from {}, member {} with address {}", new Object[] {this, member, address});
-
-            updateAsync();
-        }
-    }
-    
-    protected String getAddressOfEntity(Entity member) {
-        AttributeSensor<String> hostAndPortSensor = getHostAndPortSensor();
-        if (hostAndPortSensor != null) {
-            String result = member.getAttribute(hostAndPortSensor);
-            if (result != null) {
-                return result;
-            } else {
-                LOG.error("No host:port set for {} (using attribute {}); skipping in {}", 
-                        new Object[] {member, hostAndPortSensor, this});
-                return null;
-            }
-        } else {
-            String ip = member.getAttribute(getHostnameSensor());
-            Integer port = member.getAttribute(getPortNumberSensor());
-            if (ip!=null && port!=null) {
-                return ip+":"+port;
-            }
-            LOG.error("Unable to construct hostname:port representation for {} ({}:{}); skipping in {}", 
-                    new Object[] {member, ip, port, this});
-            return null;
-        }
-    }
-
-    // Utilities for modifying an AttributeSensor of type map
-    private static class MapAttribute {
-        public static <K, V> V put(Entity entity, AttributeSensor<Map<K,V>> attribute, K key, V value) {
-            Map<K, V> oldMap = entity.getAttribute(attribute);
-            Map<K, V> newMap = MutableMap.copyOf(oldMap);
-            V oldVal = newMap.put(key, value);
-            ((EntityInternal)entity).setAttribute(attribute, newMap);
-            return oldVal;
-        }
-        
-        public static <K, V> V remove(Entity entity, AttributeSensor<Map<K,V>> attribute, K key) {
-            Map<K, V> oldMap = entity.getAttribute(attribute);
-            Map<K, V> newMap = MutableMap.copyOf(oldMap);
-            V oldVal = newMap.remove(key);
-            ((EntityInternal)entity).setAttribute(attribute, newMap);
-            return oldVal;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedController.java b/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedController.java
deleted file mode 100644
index 47e1f86..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedController.java
+++ /dev/null
@@ -1,28 +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.proxy;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.ImplementedBy;
-
-@ImplementedBy(AbstractNonProvisionedControllerImpl.class)
-public interface AbstractNonProvisionedController extends LoadBalancer, Entity {
-
-    public boolean isActive();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
deleted file mode 100644
index 590ae32..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
+++ /dev/null
@@ -1,277 +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.proxy;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.policy.PolicySpec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.Group;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.entity.group.Cluster;
-import brooklyn.entity.trait.Startable;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.guava.Maybe;
-
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-public abstract class AbstractNonProvisionedControllerImpl extends AbstractEntity implements AbstractNonProvisionedController {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractNonProvisionedControllerImpl.class);
-    
-    protected volatile boolean isActive;
-    protected volatile boolean updateNeeded = true;
-    
-    protected AbstractMembershipTrackingPolicy serverPoolMemberTrackerPolicy;
-    protected Set<String> serverPoolAddresses = Sets.newLinkedHashSet();
-    protected Map<Entity,String> serverPoolTargets = Maps.newLinkedHashMap();
-    
-    public AbstractNonProvisionedControllerImpl() {
-        this(MutableMap.of(), null, null);
-    }
-    public AbstractNonProvisionedControllerImpl(Map properties) {
-        this(properties, null, null);
-    }
-    public AbstractNonProvisionedControllerImpl(Entity parent) {
-        this(MutableMap.of(), parent, null);
-    }
-    public AbstractNonProvisionedControllerImpl(Map properties, Entity parent) {
-        this(properties, parent, null);
-    }
-    public AbstractNonProvisionedControllerImpl(Entity parent, Cluster cluster) {
-        this(MutableMap.of(), parent, cluster);
-    }
-    public AbstractNonProvisionedControllerImpl(Map properties, Entity parent, Cluster cluster) {
-    }
-
-    public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {
-        @Override protected void onEntityEvent(EventType type, Entity member) {
-            ((AbstractNonProvisionedControllerImpl)super.entity).onServerPoolMemberChanged(member);
-        }
-    }
-
-    /**
-     * Opportunity to do late-binding of the cluster that is being controlled. Must be called before start().
-     * Can pass in the 'serverPool'.
-     */
-    @Override
-    public void bind(Map<?,?> flags) {
-        if (flags.containsKey("serverPool")) {
-            setConfigEvenIfOwned(SERVER_POOL, (Group) flags.get("serverPool"));
-        }
-    }
-
-    @Override
-    public boolean isActive() {
-        return isActive;
-    }
-    
-    @Override
-    public void start(Collection<? extends Location> locations) {
-        preStart();
-    }
-
-    @Override
-    public void stop() {
-        preStop();
-    }
-    
-    protected void preStart() {
-        AttributeSensor<?> hostAndPortSensor = getConfig(HOST_AND_PORT_SENSOR);
-        Maybe<Object> hostnameSensor = getConfigRaw(HOSTNAME_SENSOR, true);
-        Maybe<Object> portSensor = getConfigRaw(PORT_NUMBER_SENSOR, true);
-        if (hostAndPortSensor != null) {
-            checkState(!hostnameSensor.isPresent() && !portSensor.isPresent(), 
-                    "Must not set %s and either of %s or %s", HOST_AND_PORT_SENSOR, HOSTNAME_SENSOR, PORT_NUMBER_SENSOR);
-        }
-        
-        ConfigToAttributes.apply(this);
-        addServerPoolMemberTrackerPolicy();
-    }
-    
-    protected void preStop() {
-        removeServerPoolMemberTrackerPolicy();
-    }
-        
-    protected void addServerPoolMemberTrackerPolicy() {
-        Group serverPool = getServerPool();
-        if (serverPool != null) {
-            serverPoolMemberTrackerPolicy = addPolicy(PolicySpec.create(MemberTrackingPolicy.class)
-                    .displayName("Controller targets tracker")
-                    .configure("group", serverPool));
-            
-            LOG.info("Added policy {} to {}, during start", serverPoolMemberTrackerPolicy, this);
-            
-            serverPoolAddresses.clear();
-            serverPoolTargets.clear();
-                
-            // Initialize ourselves immediately with the latest set of members; don't wait for
-            // listener notifications because then will be out-of-date for short period (causing 
-            // problems for rebind)
-            for (Entity member : getServerPool().getMembers()) {
-                if (belongsInServerPool(member)) {
-                    if (LOG.isTraceEnabled()) LOG.trace("Done {} checkEntity {}", this, member);
-                    String address = getAddressOfEntity(member);
-                    serverPoolTargets.put(member, address);
-                    if (address != null) {
-                        serverPoolAddresses.add(address);
-                    }
-                }
-            }
-            
-            LOG.info("Resetting {}, members {} with addresses {}", new Object[] {this, serverPoolTargets, serverPoolAddresses});
-            setAttribute(SERVER_POOL_TARGETS, serverPoolTargets);
-        }
-    }
-    
-    protected void removeServerPoolMemberTrackerPolicy() {
-        if (serverPoolMemberTrackerPolicy != null) {
-            removePolicy(serverPoolMemberTrackerPolicy);
-        }
-    }
-    
-    /** 
-     * Implementations should update the configuration so that 'serverPoolAddresses' are targeted.
-     * The caller will subsequently call reload to apply the new configuration.
-     */
-    protected abstract void reconfigureService();
-    
-    @Override
-    public synchronized void update() {
-        if (!isActive()) updateNeeded = true;
-        else {
-            updateNeeded = false;
-            LOG.debug("Updating {} in response to changes", this);
-            reconfigureService();
-            LOG.debug("Reloading {} in response to changes", this);
-            invoke(RELOAD);
-        }
-        setAttribute(SERVER_POOL_TARGETS, serverPoolTargets);
-    }
-    
-    protected synchronized void onServerPoolMemberChanged(Entity member) {
-        if (LOG.isTraceEnabled()) LOG.trace("For {}, considering membership of {} which is in locations {}", 
-                new Object[] {this, member, member.getLocations()});
-        if (belongsInServerPool(member)) {
-            addServerPoolMember(member);
-        } else {
-            removeServerPoolMember(member);
-        }
-        if (LOG.isTraceEnabled()) LOG.trace("Done {} checkEntity {}", this, member);
-    }
-    
-    protected boolean belongsInServerPool(Entity member) {
-        if (!groovyTruth(member.getAttribute(Startable.SERVICE_UP))) {
-            if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, eliminating because not up", this, member);
-            return false;
-        }
-        if (!getServerPool().getMembers().contains(member)) {
-            if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, eliminating because not member", this, member);
-            return false;
-        }
-        if (LOG.isTraceEnabled()) LOG.trace("Members of {}, checking {}, approving", this, member);
-        return true;
-    }
-    
-    private Group getServerPool() {
-        return getConfig(SERVER_POOL);
-    }
-    
-    protected AttributeSensor<Integer> getPortNumberSensor() {
-        return getAttribute(PORT_NUMBER_SENSOR);
-    }
-    
-    protected AttributeSensor<String> getHostnameSensor() {
-        return getAttribute(HOSTNAME_SENSOR);
-    }
-
-    protected AttributeSensor<String> getHostAndPortSensor() {
-        return getAttribute(HOST_AND_PORT_SENSOR);
-    }
-
-    protected synchronized void addServerPoolMember(Entity member) {
-        if (serverPoolTargets.containsKey(member)) {
-            if (LOG.isTraceEnabled()) LOG.trace("For {}, not adding as already have member {}", new Object[] {this, member});
-            return;
-        }
-        
-        String address = getAddressOfEntity(member);
-        if (address != null) {
-            serverPoolAddresses.add(address);
-        }
-
-        LOG.info("Adding to {}, new member {} with address {}", new Object[] {this, member, address});
-        
-        update();
-        serverPoolTargets.put(member, address);
-    }
-    
-    protected synchronized void removeServerPoolMember(Entity member) {
-        if (!serverPoolTargets.containsKey(member)) {
-            if (LOG.isTraceEnabled()) LOG.trace("For {}, not removing as don't have member {}", new Object[] {this, member});
-            return;
-        }
-        
-        String address = serverPoolTargets.get(member);
-        if (address != null) {
-            serverPoolAddresses.remove(address);
-        }
-        
-        LOG.info("Removing from {}, member {} with address {}", new Object[] {this, member, address});
-        
-        update();
-        serverPoolTargets.remove(member);
-    }
-    
-    protected String getAddressOfEntity(Entity member) {
-        AttributeSensor<String> hostAndPortSensor = getHostAndPortSensor();
-        if (hostAndPortSensor != null) {
-            String result = member.getAttribute(hostAndPortSensor);
-            if (result != null) {
-                return result;
-            } else {
-                LOG.error("No host:port set for {} (using attribute {}); skipping in {}", 
-                        new Object[] {member, hostAndPortSensor, this});
-                return null;
-            }
-        } else {
-            String ip = member.getAttribute(getHostnameSensor());
-            Integer port = member.getAttribute(getPortNumberSensor());
-            if (ip!=null && port!=null) {
-                return ip+":"+port;
-            }
-            LOG.error("Unable to construct hostname:port representation for {} ({}:{}); skipping in {}", 
-                    new Object[] {member, ip, port, this});
-            return null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancer.java b/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancer.java
deleted file mode 100644
index 415dea4..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancer.java
+++ /dev/null
@@ -1,124 +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.proxy;
-
-import java.net.URI;
-import java.util.Map;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.Group;
-import brooklyn.entity.annotation.Effector;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.MethodEffector;
-import brooklyn.entity.trait.Startable;
-import brooklyn.entity.webapp.WebAppService;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.event.basic.Sensors;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.reflect.TypeToken;
-
-/**
- * A load balancer that routes requests to set(s) of servers.
- * 
- * There is an optional "serverPool" that will have requests routed to it (e.g. as round-robin). 
- * This is a group whose members are appropriate servers; membership of that group will be tracked 
- * to automatically update the load balancer's configuration as appropriate.
- * 
- * There is an optional urlMappings group for defining additional mapping rules. Members of this
- * group (of type UrlMapping) will be tracked, to automatically update the load balancer's configuration.
- * The UrlMappings can give custom routing rules so that specific urls are routed (and potentially re-written)
- * to particular sets of servers. 
- * 
- * @author aled
- */
-public interface LoadBalancer extends Entity, Startable {
-
-    @SetFromFlag("serverPool")
-    ConfigKey<Group> SERVER_POOL = new BasicConfigKey<Group>(
-            Group.class, "loadbalancer.serverpool", "The default servers to route messages to");
-
-    @SetFromFlag("urlMappings")
-    ConfigKey<Group> URL_MAPPINGS = new BasicConfigKey<Group>(
-            Group.class, "loadbalancer.urlmappings", "Special mapping rules (e.g. for domain/path matching, rewrite, etc); not supported by all load balancers");
-    
-    /** sensor for port to forward to on target entities */
-    @SuppressWarnings("serial")
-    @SetFromFlag("portNumberSensor")
-    public static final BasicAttributeSensorAndConfigKey<AttributeSensor<Integer>> PORT_NUMBER_SENSOR = new BasicAttributeSensorAndConfigKey<AttributeSensor<Integer>>(
-        new TypeToken<AttributeSensor<Integer>>() {}, "member.sensor.portNumber", "Port number sensor on members (defaults to http.port; not supported in all implementations)", Attributes.HTTP_PORT);
-
-    /** sensor for hostname to forward to on target entities */
-    @SuppressWarnings("serial")
-    @SetFromFlag("hostnameSensor")
-    public static final BasicAttributeSensorAndConfigKey<AttributeSensor<String>> HOSTNAME_SENSOR = new BasicAttributeSensorAndConfigKey<AttributeSensor<String>>(
-        new TypeToken<AttributeSensor<String>>() {}, "member.sensor.hostname", "Hostname/IP sensor on members (defaults to host.subnet.hostname; not supported in all implementations)", Attributes.SUBNET_HOSTNAME);
-
-    /** sensor for hostname to forward to on target entities */
-    @SuppressWarnings("serial")
-    @SetFromFlag("hostAndPortSensor")
-    public static final BasicAttributeSensorAndConfigKey<AttributeSensor<String>> HOST_AND_PORT_SENSOR = new BasicAttributeSensorAndConfigKey<AttributeSensor<String>>(
-            new TypeToken<AttributeSensor<String>>() {}, "member.sensor.hostandport", "host:port sensor on members (invalid to configure this and the portNumber or hostname sensors)", null);
-    
-    @SetFromFlag("port")
-    /** port where this controller should live */
-    public static final PortAttributeSensorAndConfigKey PROXY_HTTP_PORT = new PortAttributeSensorAndConfigKey(
-            "proxy.http.port", "Main port where this proxy listens if using HTTP", ImmutableList.of(8000, "8001+"));
-
-    @SetFromFlag("httpsPort")
-    /** port where this controller should live */
-    public static final PortAttributeSensorAndConfigKey PROXY_HTTPS_PORT = new PortAttributeSensorAndConfigKey(
-            "proxy.https.port", "Main port where this proxy listens if using HTTPS", ImmutableList.of(8443, "8443+"));
-
-    @SetFromFlag("protocol")
-    public static final BasicAttributeSensorAndConfigKey<String> PROTOCOL = new BasicAttributeSensorAndConfigKey<String>(
-            String.class, "proxy.protocol", "Main URL protocol this proxy answers (typically http or https)", null);
-    
-    public static final AttributeSensor<String> HOSTNAME = Attributes.HOSTNAME;
-    
-    public static final AttributeSensor<URI> MAIN_URI = Attributes.MAIN_URI;
-    public static final AttributeSensor<String> ROOT_URL = WebAppService.ROOT_URL;
-
-    @SuppressWarnings("serial")
-    public static final AttributeSensor<Map<Entity, String>> SERVER_POOL_TARGETS = Sensors.newSensor(
-            new TypeToken<Map<Entity, String>>() {},
-            "proxy.serverpool.targets", 
-            "The downstream targets in the server pool");
-    
-    public static final MethodEffector<Void> RELOAD = new MethodEffector<Void>(LoadBalancer.class, "reload");
-    
-    public static final MethodEffector<Void> UPDATE = new MethodEffector<Void>(LoadBalancer.class, "update");
-
-    @Effector(description="Forces reload of the configuration")
-    public void reload();
-
-    @Effector(description="Updates the entities configuration, and then forces reload of that configuration")
-    public void update();
-    
-    /**
-     * Opportunity to do late-binding of the cluster that is being controlled. Must be called before start().
-     * Can pass in the 'serverPool'.
-     */
-    public void bind(Map<?,?> flags);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerCluster.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerCluster.java b/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerCluster.java
deleted file mode 100644
index 1f42827..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerCluster.java
+++ /dev/null
@@ -1,37 +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.proxy;
-
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.proxying.ImplementedBy;
-
-/**
- * A cluster of load balancers, where configuring the cluster (through the LoadBalancer interface)
- * will configure all load balancers in the cluster.
- * 
- * Config keys (such as LoadBalancer.serverPool and LoadBalancer.urlMappings) are automatically
- * inherited by the children of the load balancer cluster. It is through that mechanism that
- * configuration changes on the cluster will be applied to all child load balancers (i.e. by
- * them all sharing the same serverPool and urlMappings etc).
- *  
- * @author aled
- */
-@ImplementedBy(LoadBalancerClusterImpl.class)
-public interface LoadBalancerCluster extends DynamicCluster, LoadBalancer {
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerClusterImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerClusterImpl.java
deleted file mode 100644
index b17049e..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/LoadBalancerClusterImpl.java
+++ /dev/null
@@ -1,76 +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.proxy;
-
-import java.util.Map;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.group.DynamicClusterImpl;
-
-/**
- * A cluster of load balancers, where configuring the cluster (through the LoadBalancer interface)
- * will configure all load balancers in the cluster.
- * 
- * Config keys (such as LoadBalancer.serverPool and LoadBalancer.urlMappings) are automatically
- * inherited by the children of the load balancer cluster. It is through that mechanism that
- * configuration changes on the cluster will be applied to all child load balancers (i.e. by
- * them all sharing the same serverPool and urlMappings etc).
- *  
- * @author aled
- */
-public class LoadBalancerClusterImpl extends DynamicClusterImpl implements LoadBalancerCluster {
-
-    // TODO I suspect there are races with reconfiguring the load-balancers while
-    // the cluster is growing: there is no synchronization around the calls to reload
-    // and the resize, so presumably there's a race where a newly added load-balancer 
-    // could miss the most recent reload call?
-
-    public LoadBalancerClusterImpl() {
-        super();
-    }
-
-    /* NOTE The following methods come from {@link LoadBalancer} but are probably safe to ignore */
-    
-    @Override
-    public void reload() {
-        for (Entity member : getMembers()) {
-            if (member instanceof LoadBalancer) {
-                ((LoadBalancer)member).reload();
-            }
-        }
-    }
-
-    @Override
-    public void update() {
-        for (Entity member : getMembers()) {
-            if (member instanceof LoadBalancer) {
-                ((LoadBalancer)member).update();
-            }
-        }
-    }
-
-    @Override
-    public void bind(Map<?,?> flags) {
-        for (Entity member : getMembers()) {
-            if (member instanceof LoadBalancer) {
-                ((LoadBalancer)member).bind(flags);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java b/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
deleted file mode 100644
index 0a61021..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
+++ /dev/null
@@ -1,219 +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.proxy;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.base.Objects;
-
-public class ProxySslConfig implements Serializable {
-
-    private static final long serialVersionUID = -2692754611458939617L;
-
-    private static final Logger log = LoggerFactory.getLogger(ProxySslConfig.class);
-    
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public static class Builder {
-        @SetFromFlag protected String certificateSourceUrl;
-        @SetFromFlag protected String keySourceUrl;
-        @SetFromFlag protected String certificateDestination;
-        @SetFromFlag protected String keyDestination;
-        @SetFromFlag protected boolean targetIsSsl = false;
-        @SetFromFlag protected boolean reuseSessions = false;
-
-        public Builder certificateSourceUrl(String val) {
-            certificateSourceUrl = val; return this;
-        }
-        public Builder keySourceUrl(String val) {
-            keySourceUrl = val; return this;
-        }
-        public Builder certificateDestination(String val) {
-            certificateDestination = val; return this;
-        }
-        public Builder keyDestination(String val) {
-            keyDestination = val; return this;
-        }
-        public Builder targetIsSsl(boolean val) {
-            targetIsSsl = val; return this;
-        }
-        public Builder reuseSessions(boolean val) {
-            reuseSessions = val; return this;
-        }
-        public ProxySslConfig build() {
-            ProxySslConfig result = new ProxySslConfig(this);
-            return result;
-        }
-    }
-    
-    public static ProxySslConfig fromMap(Map<?,?> map) {
-        Builder b = new Builder();
-        Map<?, ?> unused = FlagUtils.setFieldsFromFlags(map, b);
-        if (!unused.isEmpty()) log.warn("Unused flags when populating "+b+" (ignoring): "+unused);
-        return b.build();
-    }
-
-    private String certificateSourceUrl;
-    private String keySourceUrl;
-    private String certificateDestination;
-    private String keyDestination;
-    private boolean targetIsSsl = false;
-    private boolean reuseSessions = false;
-
-    public ProxySslConfig() { }
-
-    protected ProxySslConfig(Builder builder) {
-        certificateSourceUrl = builder.certificateSourceUrl;
-        keySourceUrl = builder.keySourceUrl;
-        certificateDestination = builder.certificateDestination;
-        keyDestination = builder.keyDestination;
-        targetIsSsl = builder.targetIsSsl;
-        reuseSessions = builder.reuseSessions;
-    }
-
-    /**
-     * URL for the SSL certificates required at the server.
-     * <p>
-     * Corresponding nginx settings:
-     * <pre>
-     *     ssl                  on;
-     *     ssl_certificate      www.example.com.crt;
-     *     ssl_certificate_key  www.example.com.key;
-     * </pre>
-     * Okay (in nginx) for key to be null if certificate contains both as per setup at
-     * http://nginx.org/en/docs/http/configuring_https_servers.html
-     * <p>
-     * Proxy object can be set on nginx instance to apply site-wide,
-     * and to put multiple servers in the certificate file
-     * <p>
-     * The brooklyn entity will install the certificate/key(s) on the server.
-     * (however it will not currently merge multiple certificates.
-     * if conflicting certificates are attempted to be installed nginx will complain.)
-     */
-    public String getCertificateSourceUrl() {
-        return certificateSourceUrl;
-    }
-
-    public void setCertificateSourceUrl(String certificateSourceUrl) {
-        this.certificateSourceUrl = certificateSourceUrl;
-    }
-
-    /** @see #getCertificateSourceUrl()} */
-    public String getKeySourceUrl() {
-        return keySourceUrl;
-    }
-
-    public void setKeySourceUrl(String keySourceUrl) {
-        this.keySourceUrl = keySourceUrl;
-    }
-
-    /**
-     * Sets the {@code ssl_certificate_path} to be used within the generated
-     * {@link LoadBalancer} configuration.
-     * <p>
-     * If set to null, Brooklyn will use an auto generated path.
-     * <p>
-     * If {@link #getCertificateSourceUrl() certificateSourceUrl} is set     *
-     * then Brooklyn will copy the certificate the destination.
-     * <p>
-     * Setting this field is useful if there is a {@code certificate} on the
-     * nginx machine you want to make use of.
-     */
-    public String getCertificateDestination() {
-        return certificateDestination;
-    }
-
-    public void setCertificateDestination(String certificateDestination) {
-        this.certificateDestination = certificateDestination;
-    }
-
-    /**
-     * Sets the {@code ssl_certificate_key} path to be used within the generated
-     * {@link LoadBalancer} configuration.
-     * <p>
-     * If set to null, Brooklyn will use an auto generated path.
-     * <p>
-     * If {@link #getKeySourceUrl() keySourceUrl} is set then Brooklyn will copy the
-     * certificate to the destination.
-     * <p>
-     * Setting this field is useful if there is a {@code certificate_key} on the
-     * nginx machine you want to make use of.
-     */
-    public String getKeyDestination() {
-        return keyDestination;
-    }
-
-    public void setKeyDestination(String keyDestination) {
-        this.keyDestination = keyDestination;
-    }
-
-    /**
-     * Whether the downstream server (if mapping) also expects https; default false.
-     */
-    public boolean getTargetIsSsl() {
-        return targetIsSsl;
-    }
-
-    public void setTargetIsSsl(boolean targetIsSsl) {
-        this.targetIsSsl = targetIsSsl;
-    }
-
-    /**
-     * Whether to reuse SSL validation in the server (performance).
-     * <p>
-     * Corresponds to nginx setting {@code proxy_ssl_session_reuse on|off}.
-     */
-    public boolean getReuseSessions() {
-        return reuseSessions;
-    }
-
-    public void setReuseSessions(boolean reuseSessions) {
-        this.reuseSessions = reuseSessions;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(certificateSourceUrl, keySourceUrl, certificateDestination, keyDestination, reuseSessions, targetIsSsl);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        ProxySslConfig other = (ProxySslConfig) obj;
-
-        return Objects.equal(certificateSourceUrl, other.certificateSourceUrl) &&
-                Objects.equal(certificateDestination, other.certificateDestination) &&
-                Objects.equal(keyDestination, other.keyDestination) &&
-                Objects.equal(keySourceUrl, other.keySourceUrl) &&
-                Objects.equal(reuseSessions, other.reuseSessions) &&
-                Objects.equal(targetIsSsl, other.targetIsSsl);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java
deleted file mode 100644
index 1da0ed8..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java
+++ /dev/null
@@ -1,33 +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.proxy.nginx;
-
-/**
- * Generates a {@code server.conf} configuration file for an {@link NginxController}.
- */
-public interface NginxConfigFileGenerator {
-
-    /**
-     * Entry point for the generator.
-     *
-     * @return The contents of the {@code server.conf} file
-     */
-    String generateConfigFile(NginxDriver driver, NginxController entity);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/77dff880/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java
deleted file mode 100644
index 1fdba3e..0000000
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java
+++ /dev/null
@@ -1,145 +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.proxy.nginx;
-
-import java.util.Map;
-
-import org.apache.brooklyn.catalog.Catalog;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.annotation.Effector;
-import brooklyn.entity.annotation.EffectorParam;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.MethodEffector;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.proxy.AbstractController;
-import brooklyn.entity.proxy.ProxySslConfig;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.entity.trait.HasShortName;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
-import brooklyn.event.basic.Sensors;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableMap;
-
-/**
- * An entity that represents an Nginx proxy (e.g. for routing requests to servers in a cluster).
- * <p>
- * The default driver *builds* nginx from source (because binaries are not reliably available, esp not with sticky sessions).
- * This requires gcc and other build tools installed. The code attempts to install them but inevitably 
- * this entity may be more finicky about the OS/image where it runs than others.
- * <p>
- * Paritcularly on OS X we require Xcode and command-line gcc installed and on the path.
- * <p>
- * See {@link http://library.linode.com/web-servers/nginx/configuration/basic} for useful info/examples
- * of configuring nginx.
- * <p>
- * https configuration is supported, with the certificates providable on a per-UrlMapping basis or a global basis.
- * (not supported to define in both places.) 
- * per-Url is useful if different certificates are used for different server names,
- * or different ports if that is supported.
- * see more info on Ssl in {@link ProxySslConfig}.
- */
-@Catalog(name="Nginx Server", description="A single Nginx server. Provides HTTP and reverse proxy services", iconUrl="classpath:///nginx-logo.jpeg")
-@ImplementedBy(NginxControllerImpl.class)
-public interface NginxController extends AbstractController, HasShortName {
-
-    MethodEffector<String> GET_CURRENT_CONFIGURATION =
-            new MethodEffector<String>(NginxController.class, "getCurrentConfiguration");
-
-    MethodEffector<Void> DEPLOY =
-            new MethodEffector<Void>(NginxController.class, "deploy");
-    
-    @SetFromFlag("version")
-    ConfigKey<String> SUGGESTED_VERSION =
-            ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "1.8.0");
-
-    @SetFromFlag("stickyVersion")
-    ConfigKey<String> STICKY_VERSION = ConfigKeys.newStringConfigKey(
-            "nginx.sticky.version", "Version of ngnix-sticky-module to be installed, if required", "1.2.5");
-
-    @SetFromFlag("pcreVersion")
-    ConfigKey<String> PCRE_VERSION = ConfigKeys.newStringConfigKey(
-            "pcre.version", "Version of PCRE to be installed, if required", "8.37");
-
-    @SetFromFlag("downloadUrl")
-    BasicAttributeSensorAndConfigKey<String> DOWNLOAD_URL = new BasicAttributeSensorAndConfigKey<String>(
-            SoftwareProcess.DOWNLOAD_URL, "http://nginx.org/download/nginx-${version}.tar.gz");
-
-    @SetFromFlag("downloadAddonUrls")
-    BasicAttributeSensorAndConfigKey<Map<String,String>> DOWNLOAD_ADDON_URLS = new BasicAttributeSensorAndConfigKey<Map<String,String>>(
-            SoftwareProcess.DOWNLOAD_ADDON_URLS, ImmutableMap.of(
-                    "stickymodule", "https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/${addonversion}.tar.gz",
-                    "pcre", "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-${addonversion}.tar.gz"));
-
-    @SetFromFlag("sticky")
-    ConfigKey<Boolean> STICKY = ConfigKeys.newBooleanConfigKey(
-            "nginx.sticky", "Whether to use sticky sessions", true);
-
-    @SetFromFlag("httpPollPeriod")
-    ConfigKey<Long> HTTP_POLL_PERIOD = ConfigKeys.newLongConfigKey(
-            "nginx.sensorpoll.http", "Poll period (in milliseconds)", 1000L);
-
-    @SetFromFlag("withLdOpt")
-    ConfigKey<String> WITH_LD_OPT = ConfigKeys.newStringConfigKey(
-            "nginx.install.withLdOpt", "String to pass in with --with-ld-opt=\"<val>\" (and for OS X has pcre auto-appended to this)", "-L /usr/local/lib");
-
-    @SetFromFlag("withCcOpt")
-    ConfigKey<String> WITH_CC_OPT = ConfigKeys.newStringConfigKey(
-            "nginx.install.withCcOpt", "String to pass in with --with-cc-opt=\"<val>\"", "-I /usr/local/include");
-
-    @SetFromFlag("configGenerator")
-    ConfigKey<NginxConfigFileGenerator> SERVER_CONF_GENERATOR = ConfigKeys.newConfigKey(NginxConfigFileGenerator.class,
-            "nginx.config.generator", "The server.conf generator class", new NginxDefaultConfigGenerator());
-
-    @SetFromFlag("configTemplate")
-    ConfigKey<String> SERVER_CONF_TEMPLATE_URL = NginxTemplateConfigGenerator.SERVER_CONF_TEMPLATE_URL;
-
-    @SetFromFlag("staticContentArchive")
-    ConfigKey<String> STATIC_CONTENT_ARCHIVE_URL = ConfigKeys.newStringConfigKey(
-            "nginx.config.staticContentArchiveUrl", "The URL of an archive file of static content (To be copied to the server)");
-
-    BasicAttributeSensorAndConfigKey<String> ACCESS_LOG_LOCATION = new BasicAttributeSensorAndConfigKey<String>(String.class,
-            "nginx.log.access", "Nginx access log file location", "logs/access.log");
-
-    BasicAttributeSensorAndConfigKey<String> ERROR_LOG_LOCATION = new BasicAttributeSensorAndConfigKey<String>(String.class,
-            "nginx.log.error", "Nginx error log file location", "logs/error.log");
-
-    boolean isSticky();
-
-    @Effector(description="Gets the current server configuration (by brooklyn recalculating what the config should be); does not affect the server")
-    String getCurrentConfiguration();
-
-    @Effector(description="Deploys an archive of static content to the server")
-    void deploy(@EffectorParam(name="archiveUrl", description="The URL of the static content archive to deploy") String archiveUrl);
-
-    String getConfigFile();
-
-    Iterable<UrlMapping> getUrlMappings();
-
-    boolean appendSslConfig(String id, StringBuilder out, String prefix, ProxySslConfig ssl, boolean sslBlock, boolean certificateBlock);
-    
-    public static final AttributeSensor<Boolean> NGINX_URL_ANSWERS_NICELY = Sensors.newBooleanSensor( "nginx.url.answers.nicely");
-    public static final AttributeSensor<String> PID_FILE = Sensors.newStringSensor( "nginx.pid.file", "PID file");
-    
-    public interface NginxControllerInternal {
-        public void doExtraConfigurationDuringStart();
-    }
-
-}