This closes #1129

Fix getRequiredOpenPorts in SameServerDriverLifecycleEffectorTasks
diff --git a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasks.java b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasks.java
index 4d50fad..9cd6149 100644
--- a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasks.java
+++ b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasks.java
@@ -73,23 +73,17 @@
            firewall will open the initial port instead. Mostly a problem for SameServerEntity, localhost location.
         */
         // TODO: Remove duplication between this and SoftwareProcessImpl.getRequiredOpenPorts
-        for (ConfigKey<?> k: entity.getEntityType().getConfigKeys()) {
-            Object value;
+        final Set<ConfigKey<?>> configKeys = entity.getEntityType().getConfigKeys();
+        for (ConfigKey<?> k: configKeys) {
             if (PortRange.class.isAssignableFrom(k.getType()) || k.getName().matches(".*\\.port")) {
-                value = entity.config().get(k);
-            } else {
-                // config().get() will cause this to block until all config has been resolved
-                // using config().getRaw(k) means that we won't be able to use e.g. 'http.port: $brooklyn:component("x").attributeWhenReady("foo")'
-                // but that's unlikely to be used
-                Maybe<Object> maybeValue = ((AbstractEntity.BasicConfigurationSupport)entity.config()).getRaw(k);
-                value = maybeValue.isPresent() ? maybeValue.get() : null;
-            }
-
-            Maybe<PortRange> maybePortRange = TypeCoercions.tryCoerce(value, TypeToken.of(PortRange.class));
-
-            if (maybePortRange.isPresentAndNonNull()) {
-                PortRange p = maybePortRange.get();
-                if (p != null && !p.isEmpty()) ports.add(p.iterator().next());
+                Object value = entity.config().get(k);
+                Maybe<PortRange> maybePortRange = TypeCoercions.tryCoerce(value, new TypeToken<PortRange>() {});
+                if (maybePortRange.isPresentAndNonNull()) {
+                    PortRange p = maybePortRange.get();
+                    if (p != null && !p.isEmpty()) {
+                        ports.add(p.iterator().next());
+                    }
+                }
             }
         }
         LOG.debug("getRequiredOpenPorts detected default {} for {}", ports, entity);
diff --git a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasksTest.java b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasksTest.java
new file mode 100644
index 0000000..6aa8122
--- /dev/null
+++ b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SameServerDriverLifecycleEffectorTasksTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.software.base;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class SameServerDriverLifecycleEffectorTasksTest extends BrooklynAppUnitTestSupport {
+
+    @ImplementedBy(EntityWithConfigImpl.class)
+    public interface EntityWithConfig extends Entity {
+        PortAttributeSensorAndConfigKey PORT = new PortAttributeSensorAndConfigKey(
+                "port", "port", PortRanges.fromString("1234"));
+        ConfigKey<Integer> INTEGER = ConfigKeys.newIntegerConfigKey(
+                "test.integer", "int", 1);
+        ConfigKey<Double> DOUBLE = ConfigKeys.newDoubleConfigKey(
+                "test.double", "double", 2.0);
+        ConfigKey<String> STRING = ConfigKeys.newStringConfigKey(
+                "test.string", "string", "3");
+    }
+
+    public static class EntityWithConfigImpl extends AbstractEntity implements EntityWithConfig {
+    }
+
+    @Test
+    public void testGetRequiredOpenPorts() {
+        SameServerEntity entity = app.createAndManageChild(EntitySpec.create(SameServerEntity.class).child(
+                EntitySpec.create(EntityWithConfig.class)
+                        // Previously SSDLET coerced everything TypeCoercions could handle to a port!
+                        .configure(EntityWithConfig.INTEGER, 1)
+                        .configure(EntityWithConfig.DOUBLE, 2.0)
+                        .configure(EntityWithConfig.STRING, "3")));
+        SameServerDriverLifecycleEffectorTasks effectorTasks = new SameServerDriverLifecycleEffectorTasks();
+        Collection<Integer> requiredPorts = effectorTasks.getRequiredOpenPorts(entity);
+        final ImmutableSet<Integer> expected = ImmutableSet.of(22, 1234);
+        assertEquals(requiredPorts, expected,
+                "expected=" + Iterables.toString(expected) + ", actual=" + Iterables.toString(requiredPorts));
+    }
+
+}