Repository: brooklyn-server
Updated Branches:
  refs/heads/master 601ea0d2e -> 7b5d367b8


JCLOUDS-1108 workaround: GCE hardwareId short-form


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

Branch: refs/heads/master
Commit: c5e41af2e8113113c1c6908ca43edbf29575963c
Parents: 601ea0d
Author: Aled Sage <aled.s...@gmail.com>
Authored: Mon Dec 19 18:08:04 2016 +0000
Committer: Aled Sage <aled.s...@gmail.com>
Committed: Thu Dec 22 12:37:55 2016 +0000

----------------------------------------------------------------------
 .../location/jclouds/JcloudsLocation.java       |  55 ++++++-
 .../jclouds/AbstractJcloudsLiveTest.java        |   1 -
 ...loudsGceHardwareProfilesStubbedLiveTest.java | 156 +++++++++++++++++++
 3 files changed, 210 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c5e41af2/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index 67aa826..26c89fd 100644
--- 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -1369,6 +1369,15 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
             templateBuilder.locationId(config.get(CLOUD_REGION_ID));
         }
 
+        if (Strings.isNonBlank(config.get(HARDWARE_ID))) {
+            String oldHardwareId = config.get(HARDWARE_ID);
+            String newHardwareId = transformHardwareId(oldHardwareId, config);
+            if (!Objects.equal(oldHardwareId, newHardwareId)) {
+                LOG.info("Transforming hardwareId from " + oldHardwareId + " 
to " + newHardwareId + ", in " + toString());
+                config.put(HARDWARE_ID, newHardwareId);
+            }
+        }
+
         // Apply the template builder and options properties
         for (Map.Entry<ConfigKey<?>, ? extends TemplateBuilderCustomizer> 
entry : SUPPORTED_TEMPLATE_BUILDER_PROPERTIES.entrySet()) {
             ConfigKey<?> key = entry.getKey();
@@ -1484,6 +1493,51 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         return template;
     }
 
+
+    /**
+     * See {@link https://issues.apache.org/jira/browse/JCLOUDS-1108}.
+     * 
+     * In jclouds 1.9.x and 2.0.0, google-compute-engine hardwareId must be in 
the long form. For 
+     * example {@code 
https://www.googleapis.com/compute/v1/projects/jclouds-gce/zones/us-central1-a/machineTypes/n1-standard-1}.
+     * It is much nicer to support the short-form (e.g. {@code 
n1-standard-1}), and to construct 
+     * the long-form from this.
+     * 
+     * The "zone" in the long-form needs to match the region (see {@link 
#getRegion()}).
+     * 
+     * The ideal would be for jclouds to do this. But that isn't available yet 
- in the mean time,
+     * we can make life easier for our users with the code below.
+     * 
+     * Second best would have been handling this in {@link 
TemplateBuilderCustomizers#hardwareId()}. 
+     * However, that code doesn't have enough context to know what to do 
(easily!). It is passed
+     * {@code apply(TemplateBuilder tb, ConfigBag props, Object v)}, so 
doesn't even know which 
+     * provider it is being called for (without doing ugly/brittle digging in 
the {@code props}
+     * that it is given).
+     * 
+     * Therefore we do the transform here.
+     */
+    private String transformHardwareId(String hardwareId, ConfigBag config) {
+        checkNotNull(hardwareId, "hardwareId");
+        checkNotNull(config, "config");
+        
+        String provider = getProvider();
+        String region = getRegion();
+        if (Strings.isBlank(region)) region = config.get(CLOUD_REGION_ID);
+        
+        if (!"google-compute-engine".equals(provider)) {
+            return hardwareId;
+        }
+        if (hardwareId.toLowerCase().startsWith("http") || 
hardwareId.contains("/")) {
+            // looks like it's already in long-form: don't transform
+            return hardwareId;
+        }
+        if (Strings.isNonBlank(region)) {
+            return 
String.format("https://www.googleapis.com/compute/v1/projects/jclouds-gce/zones/%s/machineTypes/%s";,
 region, hardwareId);
+        } else {
+            LOG.warn("Cannot transform GCE hardwareId (" + hardwareId + ") to 
long form, because region unknown in " + toString());
+            return hardwareId;
+        }
+    }
+
     protected String toStringNice() {
         String s = config().get(ORIGINAL_SPEC);
         if (Strings.isBlank(s)) s = config().get(NAMED_SPEC_NAME);
@@ -3051,5 +3105,4 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
             return val1;
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c5e41af2/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
index 706d308..a4d4c42 100644
--- 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
@@ -22,7 +22,6 @@ import static 
com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.InetAddress;
 import java.util.List;
 import java.util.Map;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c5e41af2/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsGceHardwareProfilesStubbedLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsGceHardwareProfilesStubbedLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsGceHardwareProfilesStubbedLiveTest.java
new file mode 100644
index 0000000..ba2128d
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsGceHardwareProfilesStubbedLiveTest.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.NoSuchElementException;
+
+import 
org.apache.brooklyn.location.jclouds.StubbedComputeServiceRegistry.BasicNodeCreator;
+import 
org.apache.brooklyn.location.jclouds.StubbedComputeServiceRegistry.NodeCreator;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class JcloudsGceHardwareProfilesStubbedLiveTest extends 
AbstractJcloudsStubbedLiveTest {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = 
LoggerFactory.getLogger(JcloudsGceHardwareProfilesStubbedLiveTest.class);
+    
+    private static final String LOCATION_SPEC = GCE_PROVIDER + ":" + 
GCE_USCENTRAL_REGION_NAME;
+    
+    private static final String N1_STANDARD_1_HARDWARE_ID = "n1-standard-1";
+    private static final String G1_SMALL_HARDWARE_ID = "g1-small";
+    private static final String N1_STANDARD_2_HARDWARE_ID = "n1-standard-2";
+    private static final String N1_HIGHCPU_4_HARDWARE_ID = "n1-highcpu-4";
+    
+    private static final String GCE_ZONES_PREFIX = 
"https://www.googleapis.com/compute/v1/projects/jclouds-gce/zones/";;
+    private static final String G1_SMALL_HARDWARE_ID_LONG_FORM = 
GCE_ZONES_PREFIX + GCE_USCENTRAL_REGION_NAME + "/machineTypes/" + 
G1_SMALL_HARDWARE_ID;
+    private static final String N1_STANDARD_1_HARDWARE_ID_LONG_FORM = 
GCE_ZONES_PREFIX + GCE_USCENTRAL_REGION_NAME + "/machineTypes/" + 
N1_STANDARD_1_HARDWARE_ID;
+    private static final String N1_STANDARD_2_HARDWARE_ID_LONG_FORM = 
GCE_ZONES_PREFIX + GCE_USCENTRAL_REGION_NAME + "/machineTypes/" + 
N1_STANDARD_2_HARDWARE_ID;
+    private static final String N1_HIGHCPU_4_HARDWARE_ID_LONG_FORM = 
GCE_ZONES_PREFIX + GCE_USCENTRAL_REGION_NAME + "/machineTypes/" + 
N1_HIGHCPU_4_HARDWARE_ID;
+    
+    private Template template;
+
+    @Override
+    protected String getLocationSpec() {
+        return LOCATION_SPEC;
+    }
+
+    @Override
+    protected NodeCreator newNodeCreator() {
+        return new BasicNodeCreator() {
+            @Override protected NodeMetadata newNode(String group, Template 
template) {
+                JcloudsGceHardwareProfilesStubbedLiveTest.this.template = 
template;
+                return super.newNode(group, template);
+            }
+        };
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareProfiles() throws Exception {
+        // default minRam is 1gb
+        obtainMachine();
+        assertTrue(template.getHardware().getRam() >= 1000, 
"template="+template);
+        assertEquals(template.getHardware().getId(), 
G1_SMALL_HARDWARE_ID_LONG_FORM, "template="+template);
+        
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_RAM, "4096"));
+        assertTrue(template.getHardware().getRam() >= 4096, 
"template="+template);
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_2_HARDWARE_ID_LONG_FORM, "template="+template);
+        
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_CORES, "4"));
+        assertTrue(template.getHardware().getProcessors().get(0).getCores() >= 
4, "template="+template);
+        assertEquals(template.getHardware().getId(), 
N1_HIGHCPU_4_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareIdLongForm() throws Exception {
+        obtainMachine(ImmutableMap.of(JcloudsLocation.HARDWARE_ID, 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM));
+        
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+    
+    @Test(groups={"Live", "Live-sanity"})
+    public void 
testJcloudsCreateWithHardwareIdLongFormWithNoRegionInLocationSpec() throws 
Exception {
+        // region will be passed in the obtain() call
+        replaceJcloudsLocation(GCE_PROVIDER);
+        
+        obtainMachine(ImmutableMap.of(
+                JcloudsLocation.CLOUD_REGION_ID, GCE_USCENTRAL_REGION_NAME, 
+                JcloudsLocation.HARDWARE_ID, 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM));
+        
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+    
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareIdLongFormWithNoRegion() throws 
Exception {
+        // Expect it to default to GCE_USCENTRAL_REGION_NAME - 
+        // but is that only because that region is hard-coded in the long 
hardwareId?!
+        replaceJcloudsLocation(GCE_PROVIDER);
+        
+        obtainMachine(ImmutableMap.of(JcloudsLocation.HARDWARE_ID, 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM));
+        
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+    
+    // See https://issues.apache.org/jira/browse/JCLOUDS-1108
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareIdShortForm() throws Exception {
+        obtainMachine(ImmutableMap.of(JcloudsLocation.HARDWARE_ID, 
N1_STANDARD_1_HARDWARE_ID));
+        
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+    
+    // See https://issues.apache.org/jira/browse/JCLOUDS-1108
+    @Test(groups={"Live", "Live-sanity"})
+    public void 
testJcloudsCreateWithHardwareIdShortFormWithNoRegionInLocationSpec() throws 
Exception {
+        replaceJcloudsLocation(GCE_PROVIDER);
+        
+        obtainMachine(ImmutableMap.of(
+                JcloudsLocation.CLOUD_REGION_ID, GCE_USCENTRAL_REGION_NAME, 
+                JcloudsLocation.HARDWARE_ID, N1_STANDARD_1_HARDWARE_ID));
+        
+        assertEquals(template.getHardware().getId(), 
N1_STANDARD_1_HARDWARE_ID_LONG_FORM, "template="+template);
+    }
+    
+    // See https://issues.apache.org/jira/browse/JCLOUDS-1108
+    // Region needs to be specified somewhere.
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareIdShortFormWithNoRegion() throws 
Exception {
+        replaceJcloudsLocation(GCE_PROVIDER);
+        
+        try {
+            obtainMachine(ImmutableMap.of(JcloudsLocation.HARDWARE_ID, 
N1_STANDARD_1_HARDWARE_ID));
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            NoSuchElementException nsee = 
Exceptions.getFirstThrowableOfType(e, NoSuchElementException.class);
+            if (nsee == null || 
!nsee.toString().contains("hardwareId("+N1_STANDARD_1_HARDWARE_ID+") not 
found")) {
+                throw e;
+            }
+        }
+    }
+}

Reply via email to