You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ri...@apache.org on 2015/06/25 16:23:34 UTC

[01/12] incubator-brooklyn git commit: Fix BROOKLYN-99

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 664849507 -> ae4c9d31b


Fix BROOKLYN-99

fix JcloudsLocationSecurityGroupCustomizer for Nova's SecurityGroupExtension
add more javadoc to JcloudsLocationSecurityGroupCustomizer


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

Branch: refs/heads/master
Commit: 57b815603652a7297a7639a03231977f30b2a8ba
Parents: 3650dfa
Author: Andrea Turli <an...@gmail.com>
Authored: Tue Jun 16 22:33:41 2015 +0200
Committer: Andrea Turli <an...@gmail.com>
Committed: Tue Jun 23 14:20:48 2015 +0200

----------------------------------------------------------------------
 .../JcloudsLocationSecurityGroupCustomizer.java | 119 ++++++++++++++-----
 ...oudsLocationSecurityGroupCustomizerTest.java |   9 +-
 2 files changed, 94 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/57b81560/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
index 7d28a9f..c3c4b27 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
@@ -25,6 +25,8 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 
+import javax.annotation.Nullable;
+
 import org.jclouds.aws.AWSResponseException;
 import org.jclouds.compute.ComputeService;
 import org.jclouds.compute.domain.SecurityGroup;
@@ -33,6 +35,8 @@ import org.jclouds.compute.extensions.SecurityGroupExtension;
 import org.jclouds.domain.Location;
 import org.jclouds.net.domain.IpPermission;
 import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.Providers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,7 +45,6 @@ import brooklyn.location.geo.LocalhostExternalIpLoader;
 import brooklyn.location.jclouds.BasicJcloudsLocationCustomizer;
 import brooklyn.location.jclouds.JcloudsLocation;
 import brooklyn.location.jclouds.JcloudsMachineLocation;
-import brooklyn.management.ManagementContext;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Cidr;
 import brooklyn.util.task.Tasks;
@@ -49,6 +52,7 @@ import brooklyn.util.time.Duration;
 
 import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
@@ -59,6 +63,7 @@ import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -66,6 +71,13 @@ import com.google.common.collect.Iterables;
 /**
  * Configures custom security groups on Jclouds locations.
  *
+ * @see SecurityGroupExtension is an optional extension to jclouds compute service. It allows the manipulation of
+ * {@link SecurityGroup}s.
+ *
+ * This customizer can be injected into {@link JcloudsLocation#obtainOnce} using
+ * It will be executed after the provisiioning of the {@link JcloudsMachineLocation} to apply app-specific
+ * customization related to the security groups.
+ *
  * @since 0.7.0
  */
 @Beta
@@ -161,7 +173,7 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
         addPermissionsToLocation(location, securityGroupDefinition.getPermissions());
         return this;
     }
-    
+
     /**
      * Applies the given security group permissions to the given location.
      * <p>
@@ -192,6 +204,7 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
             return;
         }
         final SecurityGroupExtension securityApi = computeService.getSecurityGroupExtension().get();
+        final String locationId = computeService.getContext().unwrap().getId();
 
         // Expect to have two security groups on the node: one shared between all nodes in the location,
         // that is cached in sharedGroupCache, and one created by Jclouds that is unique to the node.
@@ -202,7 +215,7 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
         try {
             machineUniqueSecurityGroup = uniqueGroupCache.get(nodeId, new Callable<SecurityGroup>() {
                 @Override public SecurityGroup call() throws Exception {
-                    SecurityGroup sg = getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(nodeId, securityApi);
+                    SecurityGroup sg = getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(nodeId, locationId, securityApi);
                     if (sg == null) {
                         throw new IllegalStateException("Failed to find machine-unique group on node: " + nodeId);
                     }
@@ -225,41 +238,47 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
      * {@link #sharedGroupCache} if no mapping for the shared group's location previously
      * existed (e.g. Brooklyn was restarted and rebound to an existing application).
      *
+     * Notice that jclouds will attach 2 securityGroups to the node if the locationId is `aws-ec2` so it needs to
+     * look for the uniqueSecurityGroup rather than the shared securityGroup.
+     *
      * @param nodeId The id of the node in question
+     * @param locationId The id of the location in question
      * @param securityApi The API to use to list security groups
      * @return the security group unique to the given node, or null if one could not be determined.
      */
-    private SecurityGroup getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(
-            String nodeId, SecurityGroupExtension securityApi) {
+    private SecurityGroup getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(String nodeId, String locationId, SecurityGroupExtension securityApi) {
         Set<SecurityGroup> groupsOnNode = securityApi.listSecurityGroupsForNode(nodeId);
-        if (groupsOnNode.size() != 2) {
-            LOG.warn("Expected to find two security groups on node {} in app {} (one shared, one unique). Found {}: {}",
-                    new Object[]{nodeId, applicationId, groupsOnNode.size(), groupsOnNode});
-            return null;
-        }
-        String expectedSharedName = getNameForSharedSecurityGroup();
-        Iterator<SecurityGroup> it = groupsOnNode.iterator();
-        SecurityGroup shared = it.next();
         SecurityGroup unique;
-        if (shared.getName().endsWith(expectedSharedName)) {
-            unique = it.next();
-        } else {
-            unique = shared;
-            shared = it.next();
-        }
-        if (!shared.getName().endsWith(expectedSharedName)) {
-            LOG.warn("Couldn't determine which security group is shared between instances in app {}. Expected={}, found={}",
-                    new Object[]{applicationId, expectedSharedName, groupsOnNode});
-            return null;
-        }
-        // Shared entry might be missing if Brooklyn has rebound to an application
-        SecurityGroup old = sharedGroupCache.asMap().putIfAbsent(shared.getLocation(), shared);
-        LOG.info("Loaded unique security group for node {} (in {}): {}",
-                new Object[]{nodeId, applicationId, unique});
-        if (old == null) {
-            LOG.info("Proactively set shared group for app {} to: {}", applicationId, shared);
+        if (locationId.equals("aws-ec2")) {
+            if (groupsOnNode.size() != 2) {
+                LOG.warn("Expected to find two security groups on node {} in app {} (one shared, one unique). Found {}: {}",
+                        new Object[]{nodeId, applicationId, groupsOnNode.size(), groupsOnNode});
+                return null;
+            }
+            String expectedSharedName = getNameForSharedSecurityGroup();
+            Iterator<SecurityGroup> it = groupsOnNode.iterator();
+            SecurityGroup shared = it.next();
+            if (shared.getName().endsWith(expectedSharedName)) {
+                unique = it.next();
+            } else {
+                unique = shared;
+                shared = it.next();
+            }
+            if (!shared.getName().endsWith(expectedSharedName)) {
+                LOG.warn("Couldn't determine which security group is shared between instances in app {}. Expected={}, found={}",
+                        new Object[]{applicationId, expectedSharedName, groupsOnNode});
+                return null;
+            }
+            // Shared entry might be missing if Brooklyn has rebound to an application
+            SecurityGroup old = sharedGroupCache.asMap().putIfAbsent(shared.getLocation(), shared);
+            LOG.info("Loaded unique security group for node {} (in {}): {}",
+                    new Object[]{nodeId, applicationId, unique});
+            if (old == null) {
+                LOG.info("Proactively set shared group for app {} to: {}", applicationId, shared);
+            }
+            return unique;
         }
-        return unique;
+        return Iterables.getOnlyElement(groupsOnNode);
     }
 
     /**
@@ -348,6 +367,11 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
      *     <li>Allow SSH access on port 22 from the world</li>
      *     <li>Allow TCP, UDP and ICMP communication between machines in the same group</li>
      * </ul>
+     *
+     * It needs to consider locationId as port ranges and groupId are cloud provider-dependent e.g openstack nova
+     * wants from 1-65535 while aws-ec2 accepts from 0-65535.
+     *
+     *
      * @param groupName The name of the security group to create
      * @param location The location in which the security group will be created
      * @param securityApi The API to use to create the security group
@@ -357,11 +381,19 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
     private SecurityGroup createBaseSecurityGroupInLocation(String groupName, Location location, SecurityGroupExtension securityApi) {
         SecurityGroup group = addSecurityGroupInLocation(groupName, location, securityApi);
 
+        Set<String> openstackNovaIds = getJcloudsLocationIds("openstack-nova");
+
+        String groupId = group.getProviderId();
+        int fromPort = 0;
+        if (location.getParent() != null && Iterables.contains(openstackNovaIds, location.getParent().getId())) {
+            groupId = group.getId();
+            fromPort = 1;
+        }
         // Note: For groupName to work with GCE we also need to tag the machines with the same ID.
         // See sourceTags section at https://developers.google.com/compute/docs/networking#firewalls
         IpPermission.Builder allWithinGroup = IpPermission.builder()
-                .groupId(group.getProviderId())
-                .fromPort(0)
+                .groupId(groupId)
+                .fromPort(fromPort)
                 .toPort(65535);
         addPermission(allWithinGroup.ipProtocol(IpProtocol.TCP).build(), group, securityApi);
         addPermission(allWithinGroup.ipProtocol(IpProtocol.UDP).build(), group, securityApi);
@@ -378,6 +410,27 @@ public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocation
         return group;
     }
 
+    private Set<String> getJcloudsLocationIds(final String jcloudsApiId) {
+        Set<String> openstackNovaProviders = FluentIterable.from(Providers.all())
+                .filter(new Predicate<ProviderMetadata>() {
+            @Override
+            public boolean apply(ProviderMetadata providerMetadata) {
+                return providerMetadata.getApiMetadata().getId().equals(jcloudsApiId);
+            }
+        }).transform(new Function<ProviderMetadata, String>() {
+            @Nullable
+            @Override
+            public String apply(ProviderMetadata input) {
+                return input.getId();
+            }
+        }).toSet();
+
+        return new ImmutableSet.Builder<String>()
+                .addAll(openstackNovaProviders)
+                .add(jcloudsApiId)
+                .build();
+    }
+
     protected SecurityGroup addSecurityGroupInLocation(final String groupName, final Location location, final SecurityGroupExtension securityApi) {
         LOG.debug("Creating security group {} in {}", groupName, location);
         Callable<SecurityGroup> callable = new Callable<SecurityGroup>() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/57b81560/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
index 643f78f..69d962f 100644
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
@@ -44,6 +44,7 @@ import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.domain.Location;
 import org.jclouds.net.domain.IpPermission;
 import org.jclouds.net.domain.IpProtocol;
+import org.mockito.Answers;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -76,7 +77,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
         customizer = new JcloudsLocationSecurityGroupCustomizer("testapp", new TestCidrSupplier());
         location = mock(Location.class);
         securityApi = mock(SecurityGroupExtension.class);
-        computeService = mock(ComputeService.class);
+        computeService = mock(ComputeService.class, Answers.RETURNS_DEEP_STUBS.get());
         when(computeService.getSecurityGroupExtension()).thenReturn(Optional.of(securityApi));
     }
 
@@ -136,6 +137,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
         SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
         SecurityGroup group = newGroup("id");
         when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, group));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         customizer.addPermissionsToLocation(ImmutableList.of(ssh, jmx), nodeId, computeService);
 
@@ -157,6 +159,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
         when(template.getLocation()).thenReturn(location);
         when(template.getOptions()).thenReturn(templateOptions);
         when(securityApi.createSecurityGroup(anyString(), eq(location))).thenReturn(sharedGroup);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         // Call customize to cache the shared group
         customizer.customize(jcloudsLocation, computeService, template);
@@ -177,6 +180,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
         SecurityGroup uniqueGroup = newGroup("unique");
 
         when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         // Expect first call to list security groups on nodeId, second to use cached version
         customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
@@ -196,6 +200,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
         when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
         when(securityApi.addIpPermission(eq(ssh), eq(uniqueGroup)))
                 .thenThrow(new RuntimeException("exception creating " + ssh));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         try {
             customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
@@ -224,6 +229,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
             }
         };
         customizer.setRetryExceptionPredicate(messageChecker);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         IpPermission ssh = newPermission(22);
         String nodeId = "node";
@@ -255,6 +261,7 @@ public class JcloudsLocationSecurityGroupCustomizerTest {
                 .thenThrow(newAwsResponseExceptionWithCode("RequestLimitExceeded"))
                 .thenThrow(newAwsResponseExceptionWithCode("Blocked"))
                 .thenReturn(sharedGroup);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
 
         try {
             customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);


[02/12] incubator-brooklyn git commit: Remove obsolete Tomcat fail binding test

Posted by ri...@apache.org.
Remove obsolete Tomcat fail binding test


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

Branch: refs/heads/master
Commit: a2660775e987628339bdc14be1c1f06839078981
Parents: d2beaa7
Author: Valentin Aitken <va...@cloudsoftcorp.com>
Authored: Tue Jun 23 15:54:54 2015 +0300
Committer: Valentin Aitken <va...@cloudsoftcorp.com>
Committed: Tue Jun 23 16:19:43 2015 +0300

----------------------------------------------------------------------
 .../Tomcat8ServerSimpleIntegrationTest.java     | 108 -------------------
 .../TomcatServerSimpleIntegrationTest.java      | 108 -------------------
 2 files changed, 216 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2660775/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/Tomcat8ServerSimpleIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/Tomcat8ServerSimpleIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/Tomcat8ServerSimpleIntegrationTest.java
deleted file mode 100644
index c8f33a7..0000000
--- a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/Tomcat8ServerSimpleIntegrationTest.java
+++ /dev/null
@@ -1,108 +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.webapp.tomcat;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.net.ServerSocket;
-import java.util.Iterator;
-
-import org.jclouds.util.Throwables2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.test.entity.TestApplication;
-import brooklyn.util.net.Networking;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * This tests the operation of the {@link Tomcat8Server} entity.
- * 
- * FIXME this test is largely superseded by WebApp*IntegrationTest which tests inter alia Tomcat
- */
-public class Tomcat8ServerSimpleIntegrationTest {
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(Tomcat8ServerSimpleIntegrationTest.class);
-    
-    /** don't use 8080 since that is commonly used by testing software; use different from other tests. */
-    static PortRange DEFAULT_HTTP_PORT_RANGE = PortRanges.fromString("7880-7980");
-    
-    private TestApplication app;
-    private Tomcat8Server tc;
-    private int httpPort;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void pickFreePort() {
-        for (Iterator<Integer> iter = DEFAULT_HTTP_PORT_RANGE.iterator(); iter.hasNext();) {
-            Integer port = iter.next();
-            if (Networking.isPortAvailable(port)) {
-                httpPort = port;
-                return;
-            }
-        }
-        fail("someone is already listening on ports "+DEFAULT_HTTP_PORT_RANGE+"; tests assume that port is free on localhost");
-    }
- 
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-	/*
-	 * TODO Tomcat's HTTP connector fails to start when the HTTP port is in use.
-	 * 
-	 * This prevents the the SERVICE_UP check from receiving an answer,
-	 * which causes the test to timeout.
-	 */
-    @Test(groups="Integration")
-    public void detectFailureIfTomcatCantBindToPort() throws Exception {
-    	ServerSocket listener = new ServerSocket(httpPort);
-        try {
-            app = ApplicationBuilder.newManagedApp(TestApplication.class);
-            tc = app.createAndManageChild(EntitySpec.create(Tomcat8Server.class)
-    			.configure("httpPort", httpPort)
-    			.configure(TomcatServer.START_TIMEOUT, Duration.ONE_MINUTE));
-            try {
-                tc.start(ImmutableList.of(app.getManagementContext().getLocationManager().manage(new LocalhostMachineProvisioningLocation())));
-                fail("Should have thrown start-exception");
-            } catch (Exception e) {
-                // LocalhostMachineProvisioningLocation does NetworkUtils.isPortAvailable, so get -1
-                IllegalArgumentException iae = Throwables2.getFirstThrowableOfType(e, IllegalArgumentException.class);
-                if (iae == null || iae.getMessage() == null || !iae.getMessage().equals("port for httpPort is null")) throw e;
-            } finally {
-                tc.stop();
-            }
-            assertFalse(tc.getAttribute(Tomcat8ServerImpl.SERVICE_UP));
-        } finally {
-            listener.close();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2660775/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerSimpleIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerSimpleIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerSimpleIntegrationTest.java
deleted file mode 100644
index 0189456..0000000
--- a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerSimpleIntegrationTest.java
+++ /dev/null
@@ -1,108 +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.webapp.tomcat;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.net.ServerSocket;
-import java.util.Iterator;
-
-import org.jclouds.util.Throwables2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.test.entity.TestApplication;
-import brooklyn.util.net.Networking;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * This tests the operation of the {@link TomcatServer} entity.
- * 
- * FIXME this test is largely superseded by WebApp*IntegrationTest which tests inter alia Tomcat
- */
-public class TomcatServerSimpleIntegrationTest {
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(TomcatServerSimpleIntegrationTest.class);
-    
-    /** don't use 8080 since that is commonly used by testing software; use different from other tests. */
-    static PortRange DEFAULT_HTTP_PORT_RANGE = PortRanges.fromString("7880-7980");
-    
-    private TestApplication app;
-    private TomcatServer tc;
-    private int httpPort;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void pickFreePort() {
-        for (Iterator<Integer> iter = DEFAULT_HTTP_PORT_RANGE.iterator(); iter.hasNext();) {
-            Integer port = iter.next();
-            if (Networking.isPortAvailable(port)) {
-                httpPort = port;
-                return;
-            }
-        }
-        fail("someone is already listening on ports "+DEFAULT_HTTP_PORT_RANGE+"; tests assume that port is free on localhost");
-    }
- 
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-	/*
-	 * TODO Tomcat's HTTP connector fails to start when the HTTP port is in use.
-	 * 
-	 * This prevents the the SERVICE_UP check from receiving an answer,
-	 * which causes the test to timeout.
-	 */
-    @Test(groups="Integration")
-    public void detectFailureIfTomcatCantBindToPort() throws Exception {
-        ServerSocket listener = new ServerSocket(httpPort);
-        try {
-            app = ApplicationBuilder.newManagedApp(TestApplication.class);
-            tc = app.createAndManageChild(EntitySpec.create(TomcatServer.class)
-            	.configure("httpPort", httpPort)
-            	.configure(TomcatServer.START_TIMEOUT, Duration.ONE_MINUTE));
-            try {
-                tc.start(ImmutableList.of(app.getManagementContext().getLocationManager().manage(new LocalhostMachineProvisioningLocation())));
-                fail("Should have thrown start-exception");
-            } catch (Exception e) {
-                // LocalhostMachineProvisioningLocation does NetworkUtils.isPortAvailable, so get -1
-                IllegalArgumentException iae = Throwables2.getFirstThrowableOfType(e, IllegalArgumentException.class);
-                if (iae == null || iae.getMessage() == null || !iae.getMessage().equals("port for httpPort is null")) throw e;
-            } finally {
-                tc.stop();
-            }
-            assertFalse(tc.getAttribute(TomcatServerImpl.SERVICE_UP));
-        } finally {
-            listener.close();
-        }
-    }
-}


[11/12] incubator-brooklyn git commit: Merge and close #713 (reviewed by @neykov)

Posted by ri...@apache.org.
Merge and close #713 (reviewed by @neykov)


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

Branch: refs/heads/master
Commit: 1591e606f576a14a0b6db5d30c722d77143c9458
Parents: ab4b127 d0f5e0a
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 15:22:54 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:54 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java     | 3 ++-
 .../java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java     | 3 ++-
 .../brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java    | 3 ++-
 .../java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java  | 3 ++-
 .../brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java  | 2 ++
 5 files changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[08/12] incubator-brooklyn git commit: Merge and close #694 (reviewed by @aledsage and @mikezaccardo)

Posted by ri...@apache.org.
Merge and close #694 (reviewed by @aledsage and @mikezaccardo)


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

Branch: refs/heads/master
Commit: 130590464cd0a681b00d826184ad73f11cb9546a
Parents: e91b4cf 57b8156
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 15:22:18 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:18 2015 +0100

----------------------------------------------------------------------
 .../JcloudsLocationSecurityGroupCustomizer.java | 119 ++++++++++++++-----
 ...oudsLocationSecurityGroupCustomizerTest.java |   9 +-
 2 files changed, 94 insertions(+), 34 deletions(-)
----------------------------------------------------------------------



[04/12] incubator-brooklyn git commit: Fixing Integration test - RubyRepIntegrationTest

Posted by ri...@apache.org.
Fixing Integration test - RubyRepIntegrationTest

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

Branch: refs/heads/master
Commit: f8e6f160f5c8decd032e6dd7b6b5df34d5eca945
Parents: 45dd549
Author: Yavor Yanchev <ya...@yanchev.com>
Authored: Wed Jun 24 12:45:13 2015 +0300
Committer: Yavor Yanchev <ya...@yanchev.com>
Committed: Wed Jun 24 12:45:13 2015 +0300

----------------------------------------------------------------------
 .../brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java   | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f8e6f160/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
index 9e9b3cb..d1b7324 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
@@ -69,10 +69,12 @@ public class RubyRepIntegrationTest {
     public void test_localhost_mysql() throws Exception {
         MySqlNode db1 = tapp.createAndManageChild(EntitySpec.create(MySqlNode.class)
                 .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
+                .configure("test.table.name", "COMMENTS")
                 .configure(MySqlNode.MYSQL_PORT, PortRanges.fromInteger(9111)));
 
         MySqlNode db2 = tapp.createAndManageChild(EntitySpec.create(MySqlNode.class)
                 .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
+                .configure("test.table.name", "COMMENTS")
                 .configure(MySqlNode.MYSQL_PORT, PortRanges.fromInteger(9112)));
 
 


[05/12] incubator-brooklyn git commit: Clarify operation of `templateOptions` config key

Posted by ri...@apache.org.
Clarify operation of `templateOptions` config key

Resolves the ambiguity around single parameters of type list. Extracts
the bulk of the code into a new standalone class and adds tests. Adds
documentation.


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

Branch: refs/heads/master
Commit: 8d95139d143826719239cf7e05b6159eb4ee5eac
Parents: 45dd549
Author: Richard Downer <ri...@apache.org>
Authored: Wed Jun 24 10:58:11 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Wed Jun 24 11:03:48 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/util/flags/MethodCoercions.java    | 183 +++++++++++++++++++
 .../util/flags/MethodCoercionsTest.java         | 146 +++++++++++++++
 docs/guide/ops/locations/index.md               |  43 +++++
 .../location/jclouds/JcloudsLocation.java       |  43 +----
 4 files changed, 376 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d95139d/core/src/main/java/brooklyn/util/flags/MethodCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/flags/MethodCoercions.java b/core/src/main/java/brooklyn/util/flags/MethodCoercions.java
new file mode 100644
index 0000000..c9f00fe
--- /dev/null
+++ b/core/src/main/java/brooklyn/util/flags/MethodCoercions.java
@@ -0,0 +1,183 @@
+/*
+ * 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.util.flags;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+import javax.annotation.Nullable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A way of binding a loosely-specified method call into a strongly-typed Java method call.
+ */
+public class MethodCoercions {
+
+    /**
+     * Returns a predicate that matches a method with the given name, and a single parameter that
+     * {@link brooklyn.util.flags.TypeCoercions#tryCoerce(Object, com.google.common.reflect.TypeToken)} can process
+     * from the given argument.
+     *
+     * @param methodName name of the method
+     * @param argument argument that is intended to be given
+     * @return a predicate that will match a compatible method
+     */
+    public static Predicate<Method> matchSingleParameterMethod(final String methodName, final Object argument) {
+        checkNotNull(methodName, "methodName");
+        checkNotNull(argument, "argument");
+
+        return new Predicate<Method>() {
+            @Override
+            public boolean apply(@Nullable Method input) {
+                if (input == null) return false;
+                if (!input.getName().equals(methodName)) return false;
+                Type[] parameterTypes = input.getGenericParameterTypes();
+                return parameterTypes.length == 1
+                        && TypeCoercions.tryCoerce(argument, TypeToken.of(parameterTypes[0])).isPresentAndNonNull();
+
+            }
+        };
+    }
+
+    /**
+     * Tries to find a single-parameter method with a parameter compatible with (can be coerced to) the argument, and
+     * invokes it.
+     *
+     * @param instance the object to invoke the method on
+     * @param methodName the name of the method to invoke
+     * @param argument the argument to the method's parameter.
+     * @return the result of the method call, or {@link brooklyn.util.guava.Maybe#absent()} if method could not be matched.
+     */
+    public static Maybe<?> tryFindAndInvokeSingleParameterMethod(final Object instance, final String methodName, final Object argument) {
+        Class<?> clazz = instance.getClass();
+        Iterable<Method> methods = Arrays.asList(clazz.getMethods());
+        Optional<Method> matchingMethod = Iterables.tryFind(methods, matchSingleParameterMethod(methodName, argument));
+        if (matchingMethod.isPresent()) {
+            Method method = matchingMethod.get();
+            try {
+                Type paramType = method.getGenericParameterTypes()[0];
+                Object coercedArgument = TypeCoercions.coerce(argument, TypeToken.of(paramType));
+                return Maybe.of(method.invoke(instance, coercedArgument));
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw Exceptions.propagate(e);
+            }
+        } else {
+            return Maybe.absent();
+        }
+    }
+
+    /**
+     * Returns a predicate that matches a method with the given name, and parameters that
+     * {@link brooklyn.util.flags.TypeCoercions#tryCoerce(Object, com.google.common.reflect.TypeToken)} can process
+     * from the given list of arguments.
+     *
+     * @param methodName name of the method
+     * @param arguments arguments that is intended to be given
+     * @return a predicate that will match a compatible method
+     */
+    public static Predicate<Method> matchMultiParameterMethod(final String methodName, final List<?> arguments) {
+        checkNotNull(methodName, "methodName");
+        checkNotNull(arguments, "arguments");
+
+        return new Predicate<Method>() {
+            @Override
+            public boolean apply(@Nullable Method input) {
+                if (input == null) return false;
+                if (!input.getName().equals(methodName)) return false;
+                int numOptionParams = arguments.size();
+                Type[] parameterTypes = input.getGenericParameterTypes();
+                if (parameterTypes.length != numOptionParams) return false;
+
+                for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
+                    if (!TypeCoercions.tryCoerce(((List) arguments).get(paramCount),
+                            TypeToken.of(parameterTypes[paramCount])).isPresentAndNonNull()) return false;
+                }
+                return true;
+            }
+        };
+    }
+
+    /**
+     * Tries to find a multiple-parameter method with each parameter compatible with (can be coerced to) the
+     * corresponding argument, and invokes it.
+     *
+     * @param instance the object to invoke the method on
+     * @param methodName the name of the method to invoke
+     * @param argument a list of the arguments to the method's parameters.
+     * @return the result of the method call, or {@link brooklyn.util.guava.Maybe#absent()} if method could not be matched.
+     */
+    public static Maybe<?> tryFindAndInvokeMultiParameterMethod(final Object instance, final String methodName, final List<?> arguments) {
+        Class<?> clazz = instance.getClass();
+        Iterable<Method> methods = Arrays.asList(clazz.getMethods());
+        Optional<Method> matchingMethod = Iterables.tryFind(methods, matchMultiParameterMethod(methodName, arguments));
+        if (matchingMethod.isPresent()) {
+            Method method = matchingMethod.get();
+            try {
+                int numOptionParams = ((List)arguments).size();
+                Object[] coercedArguments = new Object[numOptionParams];
+                for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
+                    Object argument = arguments.get(paramCount);
+                    Type paramType = method.getGenericParameterTypes()[paramCount];
+                    coercedArguments[paramCount] = TypeCoercions.coerce(argument, TypeToken.of(paramType));
+                }
+                return Maybe.of(method.invoke(instance, coercedArguments));
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw Exceptions.propagate(e);
+            }
+        } else {
+            return Maybe.absent();
+        }
+    }
+
+    /**
+     * Tries to find a method with each parameter compatible with (can be coerced to) the corresponding argument, and invokes it.
+     *
+     * @param instance the object to invoke the method on
+     * @param methodName the name of the method to invoke
+     * @param argument a list of the arguments to the method's parameters, or a single argument for a single-parameter method.
+     * @return the result of the method call, or {@link brooklyn.util.guava.Maybe#absent()} if method could not be matched.
+     */
+    public static Maybe<?> tryFindAndInvokeBestMatchingMethod(final Object instance, final String methodName, final Object argument) {
+        if (argument instanceof List) {
+            List<?> arguments = (List<?>) argument;
+
+            // ambiguous case: we can't tell if the user is using the multi-parameter syntax, or the single-parameter
+            // syntax for a method which takes a List parameter. So we try one, then fall back to the other.
+
+            Maybe<?> maybe = tryFindAndInvokeMultiParameterMethod(instance, methodName, arguments);
+            if (maybe.isAbsent())
+                maybe = tryFindAndInvokeSingleParameterMethod(instance, methodName, argument);
+
+            return maybe;
+        } else {
+            return tryFindAndInvokeSingleParameterMethod(instance, methodName, argument);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d95139d/core/src/test/java/brooklyn/util/flags/MethodCoercionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/flags/MethodCoercionsTest.java b/core/src/test/java/brooklyn/util/flags/MethodCoercionsTest.java
new file mode 100644
index 0000000..4d06ca4
--- /dev/null
+++ b/core/src/test/java/brooklyn/util/flags/MethodCoercionsTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.util.flags;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class MethodCoercionsTest {
+
+    private Method singleParameterMethod;
+    private Method multiParameterMethod;
+    private Method singleCollectionParameterMethod;
+
+    @BeforeClass
+    public void testFixtureSetUp() {
+        try {
+            singleParameterMethod = TestClass.class.getMethod("singleParameterMethod", int.class);
+            multiParameterMethod = TestClass.class.getMethod("multiParameterMethod", boolean.class, int.class);
+            singleCollectionParameterMethod = TestClass.class.getMethod("singleCollectionParameterMethod", List.class);
+        } catch (NoSuchMethodException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    @Test
+    public void testMatchSingleParameterMethod() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchSingleParameterMethod("singleParameterMethod", "42");
+        assertTrue(predicate.apply(singleParameterMethod));
+        assertFalse(predicate.apply(multiParameterMethod));
+        assertFalse(predicate.apply(singleCollectionParameterMethod));
+    }
+
+    @Test
+    public void testTryFindAndInvokeSingleParameterMethod() throws Exception {
+        TestClass instance = new TestClass();
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleParameterMethod(instance, "singleParameterMethod", "42");
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasSingleParameterMethodCalled());
+    }
+
+    @Test
+    public void testMatchMultiParameterMethod() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchMultiParameterMethod("multiParameterMethod", ImmutableList.of("true", "42"));
+        assertFalse(predicate.apply(singleParameterMethod));
+        assertTrue(predicate.apply(multiParameterMethod));
+        assertFalse(predicate.apply(singleCollectionParameterMethod));
+    }
+
+    @Test
+    public void testTryFindAndInvokeMultiParameterMethod() throws Exception {
+        TestClass instance = new TestClass();
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeMultiParameterMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42"));
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasMultiParameterMethodCalled());
+    }
+
+    @Test
+    public void testTryFindAndInvokeBestMatchingMethod() throws Exception {
+        TestClass instance = new TestClass();
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "singleParameterMethod", "42");
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasSingleParameterMethodCalled());
+
+        instance = new TestClass();
+        maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42"));
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasMultiParameterMethodCalled());
+
+        instance = new TestClass();
+        maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("fred", "joe"));
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasSingleCollectionParameterMethodCalled());
+    }
+/*
+    @Test
+    public void testMatchSingleCollectionParameterMethod() throws Exception {
+        Predicate<Method> predicate = MethodCoercions.matchSingleCollectionParameterMethod("singleCollectionParameterMethod", ImmutableList.of("42"));
+        assertFalse(predicate.apply(singleParameterMethod));
+        assertFalse(predicate.apply(multiParameterMethod));
+        assertTrue(predicate.apply(singleCollectionParameterMethod));
+    }
+
+    @Test
+    public void testTryFindAndInvokeSingleCollectionParameterMethod() throws Exception {
+        TestClass instance = new TestClass();
+        Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleCollectionParameterMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("42"));
+        assertTrue(maybe.isPresent());
+        assertTrue(instance.wasSingleCollectionParameterMethodCalled());
+    }
+*/
+    public static class TestClass {
+
+        private boolean singleParameterMethodCalled;
+        private boolean multiParameterMethodCalled;
+        private boolean singleCollectionParameterMethodCalled;
+
+        public void singleParameterMethod(int parameter) {
+            singleParameterMethodCalled = true;
+        }
+
+        public void multiParameterMethod(boolean parameter1, int parameter2) {
+            multiParameterMethodCalled = true;
+        }
+
+        public void singleCollectionParameterMethod(List<String> parameter) {
+            singleCollectionParameterMethodCalled = true;
+        }
+
+        public boolean wasSingleParameterMethodCalled() {
+            return singleParameterMethodCalled;
+        }
+
+        public boolean wasMultiParameterMethodCalled() {
+            return multiParameterMethodCalled;
+        }
+
+        public boolean wasSingleCollectionParameterMethodCalled() {
+            return singleCollectionParameterMethodCalled;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d95139d/docs/guide/ops/locations/index.md
----------------------------------------------------------------------
diff --git a/docs/guide/ops/locations/index.md b/docs/guide/ops/locations/index.md
index e6c7035..6fc5b4b 100644
--- a/docs/guide/ops/locations/index.md
+++ b/docs/guide/ops/locations/index.md
@@ -210,6 +210,49 @@ For more keys and more detail on the keys below, see
   This setting prevents scripts executed on the VMs from being deleted on completion.
   Note that some scripts run periodically so this can eventually fill a disk; it should only be used for dev/test. 
 
+###### Custom template options
+
+jclouds supports many additional options for configuring how a virtual machine is created and deployed, many of which
+are for cloud-specific features and enhancements. Brooklyn supports some of these, but if what you are looking for is
+not supported directly by Brooklyn, we instead offer a mechanism to set any parameter that is supported by the jclouds
+template options for your cloud.
+
+Part of the process for creating a virtual machine is the creation of a jclouds `TemplateOptions` object. jclouds
+providers extends this with extra options for each cloud - so when using the AWS provider, the object will be of
+type `AWSEC2TemplateOptions`. By [examining the source code](https://github.com/jclouds/jclouds/blob/jclouds-1.9.0/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java),
+you can see all of the options available to you.
+
+The `templateOptions` config key takes a map. The keys to the map are method names, and Brooklyn will find the method on
+the `TemplateOptions` instance; it then invokes the method with arguments taken from the map value. If a method takes a
+single parameter, then simply give the argument as the value of the key; if the method takes multiple parameters, the
+value of the key should be an array, containing the argument for each parameter.
+
+For example, here is a complete blueprint that sets some AWS EC2 specific options:
+
+    location: AWS_eu-west-1
+    services:
+    - type: brooklyn.entity.basic.EmptySoftwareProcess
+      provisioningProperties:
+        templateOptions:
+          subnetId: subnet-041c8373
+          mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]
+          securityGroupIds: ['sg-4db68928']
+
+Here you can see that we set three template options:
+
+- `subnetId` is an example of a single parameter method. Brooklyn will effectively try to run the statement
+  `templateOptions.subnetId("subnet-041c88373");`
+- `mapNewVolumeToDeviceName` is an example of a multiple parameter method, so the value of the key is an array.
+  Brooklyn will effectively true to run the statement `templateOptions.mapNewVolumeToDeviceName("/dev/sda1", 100, true);`
+- `securityGroupIds` demonstrates an ambiguity between the two types; Brooklyn will first try to parse the value as
+  a multiple parameter method, but there is no method that matches this parameter. In this case, Brooklyn will next try
+  to parse the value as a single parameter method which takes a parameter of type `List`; such a method does exist so
+  the operation will succeed.
+
+If the method call cannot be matched to the template options available - for example if you are trying to set an AWS EC2
+specific option but your location is an OpenStack cloud - then a warning is logged and the option is ignored.
+
+
 ### AWS VPC issues which may affect users with older AWS accounts
 
 AWS now has different default behaviour depending on the age of your AWS account and whether you used the target region before, or during, 2013.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d95139d/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index 7797138..02b7dde 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -25,6 +25,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials;
 import static org.jclouds.scriptbuilder.domain.Statements.exec;
+
+import brooklyn.util.flags.MethodCoercions;
 import io.cloudsoft.winrm4j.pywinrm.Session;
 import io.cloudsoft.winrm4j.pywinrm.WinRMFactory;
 
@@ -1292,45 +1294,8 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
                     Class<? extends TemplateOptions> clazz = options.getClass();
                     Iterable<Method> methods = Arrays.asList(clazz.getMethods());
                     for(final Map.Entry<String, Object> option : optionsMap.entrySet()) {
-                        Optional<Method> methodOptional = Iterables.tryFind(methods, new Predicate<Method>() {
-                            @Override
-                            public boolean apply(@Nullable Method input) {
-                                // Matches a method with the expected name, and a single parameter that TypeCoercions
-                                // can coerce to
-                                if (input == null) return false;
-                                if (!input.getName().equals(option.getKey())) return false;
-                                int numOptionParams = option.getValue() instanceof List ? ((List)option.getValue()).size() : 1;
-                                Type[] parameterTypes = input.getGenericParameterTypes();
-                                if (parameterTypes.length != numOptionParams) return false;
-                                if (numOptionParams == 1 && !(option.getValue() instanceof List) && parameterTypes.length == 1) {
-                                    return true;
-                                }
-                                for (int paramCount = 0; paramCount < numOptionParams; paramCount ++) {
-                                    if (!TypeCoercions.tryCoerce(((List)option.getValue()).get(paramCount),
-                                            TypeToken.of(parameterTypes[paramCount])).isPresentAndNonNull()) return false;
-                                }
-                                return true;
-                            }
-                        });
-                        if(methodOptional.isPresent()) {
-                            try {
-                                Method method = methodOptional.get();
-                                if (option.getValue() instanceof List) {
-                                    List<Object> parameters = Lists.newArrayList();
-                                    int numOptionParams = ((List)option.getValue()).size();
-                                    for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
-                                        parameters.add(TypeCoercions.coerce(((List)option.getValue()).get(paramCount), TypeToken.of(method.getGenericParameterTypes()[paramCount])));
-                                    }
-                                    method.invoke(options, parameters.toArray());
-                                } else {
-                                    method.invoke(options, TypeCoercions.coerce(option.getValue(), TypeToken.of(method.getGenericParameterTypes()[0])));
-                                }
-                            } catch (IllegalAccessException e) {
-                                throw Exceptions.propagate(e);
-                            } catch (InvocationTargetException e) {
-                                throw Exceptions.propagate(e);
-                            }
-                        } else {
+                        Maybe<?> result = MethodCoercions.tryFindAndInvokeBestMatchingMethod(options, option.getKey(), option.getValue());
+                        if(result.isAbsent()) {
                             LOG.warn("Ignoring request to set template option {} because this is not supported by {}", new Object[] { option.getKey(), clazz.getCanonicalName() });
                         }
                     }


[12/12] incubator-brooklyn git commit: Merge and close #714 (reviewed by @mikezaccardo)

Posted by ri...@apache.org.
Merge and close #714 (reviewed by @mikezaccardo)


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

Branch: refs/heads/master
Commit: ae4c9d31bdf766d4dd23eda62e439998f5d676f4
Parents: 1591e60 8d95139
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 15:22:58 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:58 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/util/flags/MethodCoercions.java    | 183 +++++++++++++++++++
 .../util/flags/MethodCoercionsTest.java         | 146 +++++++++++++++
 docs/guide/ops/locations/index.md               |  43 +++++
 .../location/jclouds/JcloudsLocation.java       |  43 +----
 4 files changed, 376 insertions(+), 39 deletions(-)
----------------------------------------------------------------------



[07/12] incubator-brooklyn git commit: Add another test resource check for the source release

Posted by ri...@apache.org.
Add another test resource check for the source release


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

Branch: refs/heads/master
Commit: e91b4cf03582252829b837974b9f4c6e0a733e5f
Parents: 6648495
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 14:55:08 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:12 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e91b4cf0/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java b/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
index 78cebd2..6863c4c 100644
--- a/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
+++ b/core/src/test/java/brooklyn/management/osgi/OsgiVersionMoreEntityTest.java
@@ -198,13 +198,15 @@ public class OsgiVersionMoreEntityTest {
     }
 
     public static CatalogItem<?, ?> addMoreEntityV1(ManagementContext mgmt, String versionToRegister) {
-        return addCatalogItemWithNameAndType(mgmt, 
+        TestResourceUnavailableException.throwIfResourceUnavailable(OsgiVersionMoreEntityTest.class, BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
+        return addCatalogItemWithNameAndType(mgmt,
             OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
             versionToRegister,
             OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
             BROOKLYN_TEST_MORE_ENTITIES_V1_URL);
     }
     public static CatalogItem<?, ?> addMoreEntityV2(ManagementContext mgmt, String versionToRegister) {
+        TestResourceUnavailableException.throwIfResourceUnavailable(OsgiVersionMoreEntityTest.class, BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
         return addCatalogItemWithNameAndType(mgmt,
             OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
             versionToRegister,


[10/12] incubator-brooklyn git commit: Merge and close #712 (reviewed by @neykov and @mikezaccardo)

Posted by ri...@apache.org.
Merge and close #712 (reviewed by @neykov and @mikezaccardo)


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

Branch: refs/heads/master
Commit: ab4b127528baa757f374573e283aaf8a5ad89309
Parents: 3f41fa0 67fcc4d
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 15:22:46 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:46 2015 +0100

----------------------------------------------------------------------
 .../io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java  | 2 +-
 .../src/test/resources/java-web-app-and-db-with-function.yaml  | 4 ++--
 .../src/test/resources/java-web-app-and-db-with-policy.yaml    | 2 +-
 usage/camp/src/test/resources/java-web-app-simple.yaml         | 6 +++---
 usage/camp/src/test/resources/visitors-creation-script.sql     | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------



[06/12] incubator-brooklyn git commit: Fixing Integration test - MySQL tests

Posted by ri...@apache.org.
Fixing Integration test - MySQL tests

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

Branch: refs/heads/master
Commit: d0f5e0a4149fc648f6a3b964e94f12049f991c42
Parents: f8e6f16
Author: Yavor Yanchev <ya...@yanchev.com>
Authored: Wed Jun 24 18:17:18 2015 +0300
Committer: Yavor Yanchev <ya...@yanchev.com>
Committed: Wed Jun 24 18:17:18 2015 +0300

----------------------------------------------------------------------
 .../java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java     | 3 ++-
 .../java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java     | 3 ++-
 .../brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java    | 3 ++-
 .../java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java  | 3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d0f5e0a4/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
index 0e39c50..4bd46c2 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
@@ -34,7 +34,8 @@ public class MySqlLiveEc2Test extends AbstractEc2LiveTest {
     @Override
     protected void doTest(Location loc) throws Exception {
         MySqlNode mysql = app.createAndManageChild(EntitySpec.create(MySqlNode.class)
-                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT));
+                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
+                .configure("test.table.name", "COMMENTS"));
 
         app.start(ImmutableList.of(loc));
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d0f5e0a4/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
index 0cc20ef..9d2b48c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
@@ -34,7 +34,8 @@ public class MySqlLiveGceTest extends AbstractGoogleComputeLiveTest {
     @Override
     protected void doTest(Location loc) throws Exception {
         MySqlNode mysql = app.createAndManageChild(EntitySpec.create(MySqlNode.class)
-                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT));
+                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
+                .configure("test.table.name", "COMMENTS"));
 
         app.start(ImmutableList.of(loc));
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d0f5e0a4/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
index 8fdf558..d8cdd64 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
@@ -87,7 +87,8 @@ public class MySqlLiveRackspaceTest extends MySqlIntegrationTest {
 
     public void test(String osRegex) throws Exception {
         MySqlNode mysql = app.createAndManageChild(EntitySpec.create(MySqlNode.class)
-                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT));
+                .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT)
+                .configure("test.table.name", "COMMENTS"));
 
         BrooklynProperties brooklynProperties = mgmt.getBrooklynProperties();
         brooklynProperties.put("brooklyn.location.jclouds.rackspace-cloudservers-uk.imageNameRegex", osRegex);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d0f5e0a4/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
index b1df1d2..0abebbb 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
@@ -33,7 +33,8 @@ public class MysqlDockerLiveTest extends AbstractDockerLiveTest {
     @Override
     protected void doTest(Location loc) throws Exception {
        MySqlNode mysql = app.createAndManageChild(EntitySpec.create(MySqlNode.class)
-               .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT));
+               .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
+               .configure("test.table.name", "COMMENTS"));
 
        app.start(ImmutableList.of(loc));
 


[09/12] incubator-brooklyn git commit: Merge and close #710 (reviewed by @neykov and @mikezaccardo)

Posted by ri...@apache.org.
Merge and close #710 (reviewed by @neykov and @mikezaccardo)


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

Branch: refs/heads/master
Commit: 3f41fa0c88c590253e9a4c2f2591b695018f1efd
Parents: 1305904 a266077
Author: Richard Downer <ri...@apache.org>
Authored: Thu Jun 25 15:22:36 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu Jun 25 15:22:36 2015 +0100

----------------------------------------------------------------------
 .../Tomcat8ServerSimpleIntegrationTest.java     | 108 -------------------
 .../TomcatServerSimpleIntegrationTest.java      | 108 -------------------
 2 files changed, 216 deletions(-)
----------------------------------------------------------------------



[03/12] incubator-brooklyn git commit: Fixing Integration tests for 0.7.0

Posted by ri...@apache.org.
Fixing Integration tests for 0.7.0

- io.brooklyn.camp.brooklyn.JavaWebAppsIntegrationTest.testWithDbDeploy()
- io.brooklyn.camp.brooklyn.JavaWebAppsIntegrationTest.testWithPolicyDeploy()

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

Branch: refs/heads/master
Commit: 67fcc4ddb8dae41a87acde52d1691ce69996a0e7
Parents: 3650dfa
Author: Yavor Yanchev <ya...@yanchev.com>
Authored: Tue Jun 23 17:50:56 2015 +0300
Committer: Yavor Yanchev <ya...@yanchev.com>
Committed: Tue Jun 23 18:37:00 2015 +0300

----------------------------------------------------------------------
 .../io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java  | 2 +-
 .../src/test/resources/java-web-app-and-db-with-function.yaml  | 4 ++--
 .../src/test/resources/java-web-app-and-db-with-policy.yaml    | 2 +-
 usage/camp/src/test/resources/java-web-app-simple.yaml         | 6 +++---
 usage/camp/src/test/resources/visitors-creation-script.sql     | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/67fcc4dd/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
index bda6bd9..eb14811 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
@@ -111,7 +111,7 @@ public class JavaWebAppsIntegrationTest {
             Entities.dumpInfo(app);
 
             Assert.assertEquals(app.getChildren().size(), 1);
-            Assert.assertEquals(app.getChildren().iterator().next().getDisplayName(), "jboss1");
+            Assert.assertEquals(app.getChildren().iterator().next().getDisplayName(), "tomcat1");
             Assert.assertEquals(app.getChildren().iterator().next().getLocations().size(), 1);
             
             final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/67fcc4dd/usage/camp/src/test/resources/java-web-app-and-db-with-function.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/java-web-app-and-db-with-function.yaml b/usage/camp/src/test/resources/java-web-app-and-db-with-function.yaml
index 087e160..cb9a00e 100644
--- a/usage/camp/src/test/resources/java-web-app-and-db-with-function.yaml
+++ b/usage/camp/src/test/resources/java-web-app-and-db-with-function.yaml
@@ -22,11 +22,11 @@ services:
   name: My Web
   location: localhost
   brooklyn.config:
-    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0-M2/brooklyn-example-hello-world-sql-webapp-0.6.0-M2.war
+    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.7.0-M1/brooklyn-example-hello-world-sql-webapp-0.7.0-M1.war
     http.port: 9280+
     proxy.http.port: 9210+
     java.sysprops: 
-      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
          component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
 - serviceType: brooklyn.entity.database.mysql.MySqlNode
   id: db

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/67fcc4dd/usage/camp/src/test/resources/java-web-app-and-db-with-policy.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/java-web-app-and-db-with-policy.yaml b/usage/camp/src/test/resources/java-web-app-and-db-with-policy.yaml
index cd4c24d..107686c 100644
--- a/usage/camp/src/test/resources/java-web-app-and-db-with-policy.yaml
+++ b/usage/camp/src/test/resources/java-web-app-and-db-with-policy.yaml
@@ -26,7 +26,7 @@ services:
     http.port: 9280+
     proxy.http.port: 9210+
     java.sysprops: 
-      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s\\&password=%s",
+      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
          component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
   brooklyn.policies:
   - policyType: brooklyn.policy.autoscaling.AutoScalerPolicy

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/67fcc4dd/usage/camp/src/test/resources/java-web-app-simple.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/java-web-app-simple.yaml b/usage/camp/src/test/resources/java-web-app-simple.yaml
index 7cde93a..558b272 100644
--- a/usage/camp/src/test/resources/java-web-app-simple.yaml
+++ b/usage/camp/src/test/resources/java-web-app-simple.yaml
@@ -21,8 +21,8 @@ description: Single JBoss using Brooklyn
 origin: https://github.com/apache/incubator-brooklyn
 location: localhost
 services:
-- serviceType: brooklyn.entity.webapp.jboss.JBoss7Server
-  name: jboss1
+- serviceType: brooklyn.entity.webapp.tomcat.Tomcat8Server
+  name: tomcat1
   brooklyn.config:
-    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-webapp/0.5.0/brooklyn-example-hello-world-webapp-0.5.0.war
+    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-webapp/0.7.0-M1/brooklyn-example-hello-world-webapp-0.7.0-M1.war
     http.port: 9280+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/67fcc4dd/usage/camp/src/test/resources/visitors-creation-script.sql
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/visitors-creation-script.sql b/usage/camp/src/test/resources/visitors-creation-script.sql
index 2422f8f..a324d2e 100644
--- a/usage/camp/src/test/resources/visitors-creation-script.sql
+++ b/usage/camp/src/test/resources/visitors-creation-script.sql
@@ -20,7 +20,7 @@ create database visitors;
 use visitors;
 
 # not necessary to create user if we grant (and not supported in some dialects)
-# create user 'brooklyn' identified by 'br00k11n';
+create user 'brooklyn' identified by 'br00k11n';
 
 grant usage on *.* to 'brooklyn'@'%' identified by 'br00k11n';