You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/07/09 17:43:14 UTC
[1/2] git commit: JCLOUDS-607: ComputeService.createNodesInGroup
throws NPE on FloatingIPApi.create()
Repository: jclouds
Updated Branches:
refs/heads/1.7.x f52a264b8 -> e94b878b2
JCLOUDS-607: ComputeService.createNodesInGroup throws NPE on FloatingIPApi.create()
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/7641bd61
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/7641bd61
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/7641bd61
Branch: refs/heads/1.7.x
Commit: 7641bd61cd56f7f5a4da5ac89769c1d200abe79f
Parents: f52a264
Author: Christopher Dancy <da...@pega.com>
Authored: Mon Jun 30 16:01:43 2014 -0400
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Jul 9 17:26:57 2014 +0200
----------------------------------------------------------------------
.../AllocateAndAddFloatingIpToNode.java | 95 ++++++++++++++------
.../options/NodeAndNovaTemplateOptions.java | 54 +++++++++++
.../compute/options/NovaTemplateOptions.java | 57 +++++++++++-
...desWithGroupEncodedIntoNameThenAddToSet.java | 19 +++-
...llocateAndAddFloatingIpToNodeExpectTest.java | 56 +++++++++++-
.../rest/InsufficientResourcesException.java | 6 +-
6 files changed, 248 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
index f7c18ee..e1801b9 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
@@ -19,8 +19,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Resource;
@@ -32,6 +33,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.compute.options.NodeAndNovaTemplateOptions;
import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
@@ -39,6 +41,7 @@ import org.jclouds.rest.InsufficientResourcesException;
import com.google.common.base.Function;
import com.google.common.base.Objects;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
@@ -51,7 +54,7 @@ import com.google.common.collect.Lists;
* @author Adrian Cole
*/
public class AllocateAndAddFloatingIpToNode implements
- Function<AtomicReference<NodeMetadata>, AtomicReference<NodeMetadata>> {
+ Function<AtomicReference<NodeAndNovaTemplateOptions>, AtomicReference<NodeMetadata>> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
@@ -70,41 +73,79 @@ public class AllocateAndAddFloatingIpToNode implements
}
@Override
- public AtomicReference<NodeMetadata> apply(AtomicReference<NodeMetadata> input) {
- checkState(nodeRunning.apply(input), "node never achieved state running %s", input.get());
- NodeMetadata node = input.get();
+ public AtomicReference<NodeMetadata> apply(AtomicReference<NodeAndNovaTemplateOptions> input) {
+ checkState(nodeRunning.apply(input.get().getNodeMetadata()), "node never achieved state running %s", input.get().getNodeMetadata());
+ NodeMetadata node = input.get().getNodeMetadata().get();
// node's location is a host
String zoneId = node.getLocation().getParent().getId();
FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(zoneId).get();
+ Optional<Set<String>> poolNames = input.get().getNovaTemplateOptions().get().getFloatingIpPoolNames();
+
+ Optional<FloatingIP> ip = allocateFloatingIPForNode(floatingIpApi, poolNames, node.getId());
+ if (!ip.isPresent()) {
+ throw new InsufficientResourcesException("Failed to allocate a FloatingIP for node(" + node.getId() + ")");
+ }
+ logger.debug(">> adding floatingIp(%s) to node(%s)", ip.get().getIp(), node.getId());
+ floatingIpApi.addToServer(ip.get().getIp(), node.getProviderId());
+ input.get().getNodeMetadata().set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.get().getIp())).build());
+ floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
+ return input.get().getNodeMetadata();
+ }
+
+ /**
+ * Allocates a FloatingIP for a given Node
+ *
+ * @param floatingIpApi FloatingIPApi to create or query for a valid FloatingIP
+ * @param poolNames optional set of pool names from which we will attempt to allocate an IP from. Most cases this is null
+ * @param nodeID optional id of the Node we are trying to allocate a FloatingIP for. Used here only for logging purposes
+ * @return Optional<FloatingIP>
+ */
+ private Optional<FloatingIP> allocateFloatingIPForNode(FloatingIPApi floatingIpApi, Optional<Set<String>> poolNames, String nodeID) {
+
FloatingIP ip = null;
+
+ // 1.) Attempt to allocate from optionally passed poolNames
+ if (poolNames.isPresent()) {
+ for (String poolName : poolNames.get()){
+ try {
+ logger.debug(">> allocating floating IP from pool %s for node(%s)", poolName, nodeID);
+ ip = floatingIpApi.allocateFromPool(poolName);
+ if (ip != null)
+ return Optional.of(ip);
+ } catch (InsufficientResourcesException ire){
+ logger.trace("<< [%s] failed to allocate floating IP from pool %s for node(%s)", ire.getMessage(), poolName, nodeID);
+ }
+ }
+ }
+
+ // 2.) Attempt to allocate, if necessary, via 'create()' call
try {
- logger.debug(">> allocating or reassigning floating ip for node(%s)", node.getId());
+ logger.debug(">> creating floating IP for node(%s)", nodeID);
ip = floatingIpApi.create();
- } catch (InsufficientResourcesException e) {
- logger.trace("<< [%s] allocating a new floating ip for node(%s)", e.getMessage(), node.getId());
- logger.trace(">> searching for existing, unassigned floating ip for node(%s)", node.getId());
- ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
- new Predicate<FloatingIP>() {
-
- @Override
- public boolean apply(FloatingIP arg0) {
- return arg0.getFixedIp() == null;
- }
-
- }));
- // try to prevent multiple parallel launches from choosing the same ip.
- Collections.shuffle(unassignedIps);
- ip = Iterables.getLast(unassignedIps);
+ if(ip != null)
+ return Optional.of(ip);
+ } catch (InsufficientResourcesException ire){
+ logger.trace("<< [%s] failed to create floating IP for node(%s)", ire.getMessage(), nodeID);
}
- logger.debug(">> adding floatingIp(%s) to node(%s)", ip.getIp(), node.getId());
+
+ // 3.) If no IP was found make final attempt by searching through list of available IP's
+ logger.trace(">> searching for existing, unassigned floating IP for node(%s)", nodeID);
+ List<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
+ new Predicate<FloatingIP>() {
- floatingIpApi.addToServer(ip.getIp(), node.getProviderId());
- input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
- floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
- return input;
- }
+ @Override
+ public boolean apply(FloatingIP arg0) {
+ return arg0.getFixedIp() == null;
+ }
+ }));
+ // try to prevent multiple parallel launches from choosing the same ip.
+ Collections.shuffle(unassignedIps);
+ ip = Iterables.getLast(unassignedIps);
+ return Optional.fromNullable(ip);
+ }
+
@Override
public String toString() {
return Objects.toStringHelper("AllocateAndAddFloatingIpToNode").toString();
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NodeAndNovaTemplateOptions.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NodeAndNovaTemplateOptions.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NodeAndNovaTemplateOptions.java
new file mode 100644
index 0000000..d95e817
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NodeAndNovaTemplateOptions.java
@@ -0,0 +1,54 @@
+/*
+ * 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.jclouds.openstack.nova.v2_0.compute.options;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import com.google.common.util.concurrent.Atomics;
+
+/**
+ * Simple data-structure for holding a NodeMetadata object along with a
+ * corresponding NovaTemplateOptions object.
+ */
+public class NodeAndNovaTemplateOptions {
+
+ private final AtomicReference<NodeMetadata> nodeMetadata;
+ private final AtomicReference<NovaTemplateOptions> novaTemplateOptions;
+
+ protected NodeAndNovaTemplateOptions(AtomicReference<NodeMetadata> nodeMetadata, AtomicReference<NovaTemplateOptions> novaTemplateOptions){
+ this.nodeMetadata = nodeMetadata;
+ this.novaTemplateOptions = novaTemplateOptions;
+ }
+
+ public AtomicReference<NodeMetadata> getNodeMetadata() {
+ return nodeMetadata;
+ }
+
+ public AtomicReference<NovaTemplateOptions> getNovaTemplateOptions() {
+ return novaTemplateOptions;
+ }
+
+ public static NodeAndNovaTemplateOptions newReference(AtomicReference<NodeMetadata> node, AtomicReference<NovaTemplateOptions> options){
+ return new NodeAndNovaTemplateOptions(node, options);
+ }
+
+ public static AtomicReference<NodeAndNovaTemplateOptions> newAtomicReference(AtomicReference<NodeMetadata> node, AtomicReference<NovaTemplateOptions> options){
+ return Atomics.newReference(NodeAndNovaTemplateOptions.newReference(node, options));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NovaTemplateOptions.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NovaTemplateOptions.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NovaTemplateOptions.java
index 24328b8..4e6ce2e 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NovaTemplateOptions.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/options/NovaTemplateOptions.java
@@ -66,6 +66,8 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
if (to instanceof NovaTemplateOptions) {
NovaTemplateOptions eTo = NovaTemplateOptions.class.cast(to);
eTo.autoAssignFloatingIp(shouldAutoAssignFloatingIp());
+ if (getFloatingIpPoolNames().isPresent())
+ eTo.floatingIpPoolNames(getFloatingIpPoolNames().get());
if (getSecurityGroupNames().isPresent())
eTo.securityGroupNames(getSecurityGroupNames().get());
eTo.generateKeyPair(shouldGenerateKeyPair());
@@ -83,6 +85,7 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
}
protected boolean autoAssignFloatingIp = false;
+ protected Optional<Set<String>> floatingIpPoolNames = Optional.absent();
protected Optional<Set<String>> securityGroupNames = Optional.absent();
protected boolean generateKeyPair = false;
protected String keyPairName;
@@ -99,6 +102,7 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
return false;
NovaTemplateOptions that = NovaTemplateOptions.class.cast(o);
return super.equals(that) && equal(this.autoAssignFloatingIp, that.autoAssignFloatingIp)
+ && equal(this.floatingIpPoolNames, that.floatingIpPoolNames)
&& equal(this.securityGroupNames, that.securityGroupNames)
&& equal(this.generateKeyPair, that.generateKeyPair)
&& equal(this.keyPairName, that.keyPairName)
@@ -110,7 +114,7 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
@Override
public int hashCode() {
- return Objects.hashCode(super.hashCode(), autoAssignFloatingIp, securityGroupNames, generateKeyPair, keyPairName, userData, diskConfig, configDrive, novaNetworks);
+ return Objects.hashCode(super.hashCode(), autoAssignFloatingIp, floatingIpPoolNames, securityGroupNames, generateKeyPair, keyPairName, userData, diskConfig, configDrive, novaNetworks);
}
@Override
@@ -118,6 +122,8 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
ToStringHelper toString = super.string();
if (!autoAssignFloatingIp)
toString.add("autoAssignFloatingIp", autoAssignFloatingIp);
+ if (floatingIpPoolNames.isPresent())
+ toString.add("floatingIpPoolNames", floatingIpPoolNames.get());
if (securityGroupNames.isPresent())
toString.add("securityGroupNames", securityGroupNames.get());
if (generateKeyPair)
@@ -133,12 +139,29 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
public static final NovaTemplateOptions NONE = new NovaTemplateOptions();
/**
- * @see #shouldAutoAssignFloatingIp()
+ * @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions autoAssignFloatingIp(boolean enable) {
this.autoAssignFloatingIp = enable;
return this;
}
+
+ /**
+ * @see #getFloatingIpPoolNames()
+ */
+ public NovaTemplateOptions floatingIpPoolNames(String... floatingIpPoolNames) {
+ return floatingIpPoolNames(ImmutableSet.copyOf(checkNotNull(floatingIpPoolNames, "floatingIpPoolNames")));
+ }
+
+ /**
+ * @see #getFloatingIpPoolNames()
+ */
+ public NovaTemplateOptions floatingIpPoolNames(Iterable<String> floatingIpPoolNames) {
+ for (String groupName : checkNotNull(floatingIpPoolNames, "floatingIpPoolNames"))
+ checkNotNull(emptyToNull(groupName), "all floating-ip-pool-names must be non-empty");
+ this.floatingIpPoolNames = Optional.<Set<String>> of(ImmutableSet.copyOf(floatingIpPoolNames));
+ return this;
+ }
/**
* @see #shouldGenerateKeyPair()
@@ -187,13 +210,25 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
}
/**
+ * The floating IP pool name(s) to use when allocating a FloatingIP. Applicable
+ * only if #shouldAutoAssignFloatingIp() returns true. If not set will attempt to
+ * use whatever FloatingIP(s) can be found regardless of which pool they originated
+ * from
+ *
+ * @return floating-ip-pool names to use
+ */
+ public Optional<Set<String>> getFloatingIpPoolNames() {
+ return floatingIpPoolNames;
+ }
+
+ /**
* Specifies the keypair used to run instances with
* @return the keypair to be used
*/
public String getKeyPairName() {
return keyPairName;
}
-
+
/**
* <h3>Note</h3>
*
@@ -251,6 +286,22 @@ public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
}
/**
+ * @see #getFloatingIpPoolNames()
+ */
+ public NovaTemplateOptions floatingIpPoolNames(String... floatingIpPoolNames) {
+ NovaTemplateOptions options = new NovaTemplateOptions();
+ return NovaTemplateOptions.class.cast(options.floatingIpPoolNames(floatingIpPoolNames));
+ }
+
+ /**
+ * @see #getFloatingIpPoolNames()
+ */
+ public NovaTemplateOptions floatingIpPoolNames(Iterable<String> floatingIpPoolNames) {
+ NovaTemplateOptions options = new NovaTemplateOptions();
+ return NovaTemplateOptions.class.cast(options.floatingIpPoolNames(floatingIpPoolNames));
+ }
+
+ /**
* @see NovaTemplateOptions#shouldGenerateKeyPair()
*/
public static NovaTemplateOptions generateKeyPair(boolean enable) {
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index e3ea4cc..2ba160c 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/strategy/ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -42,16 +42,19 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.compute.functions.AllocateAndAddFloatingIpToNode;
+import org.jclouds.openstack.nova.v2_0.compute.options.NodeAndNovaTemplateOptions;
import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Multimap;
import com.google.common.primitives.Ints;
+import com.google.common.util.concurrent.Atomics;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
@@ -153,13 +156,21 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
final String name, Template template) {
ListenableFuture<AtomicReference<NodeMetadata>> future = super.createNodeInGroupWithNameAndTemplate(group, name, template);
- NovaTemplateOptions templateOptions = NovaTemplateOptions.class.cast(template.getOptions());
-
+ final NovaTemplateOptions templateOptions = NovaTemplateOptions.class.cast(template.getOptions());
if (templateOptions.shouldAutoAssignFloatingIp()) {
- return Futures.transform(future, createAndAddFloatingIpToNode, userExecutor);
+
+ ListenableFuture<AtomicReference<NodeAndNovaTemplateOptions>> nodeAndNovaTemplateOptions = Futures.transform(future,
+ new Function<AtomicReference<NodeMetadata>, AtomicReference<NodeAndNovaTemplateOptions>>(){
+
+ @Override
+ public AtomicReference<NodeAndNovaTemplateOptions> apply(AtomicReference<NodeMetadata> input) {
+ return NodeAndNovaTemplateOptions.newAtomicReference(input, Atomics.newReference(templateOptions));
+ }
+ }
+ );
+ return Futures.transform(nodeAndNovaTemplateOptions, createAndAddFloatingIpToNode, userExecutor);
} else {
return future;
}
}
-
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNodeExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNodeExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNodeExpectTest.java
index a5631ca..8edf4a5 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNodeExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNodeExpectTest.java
@@ -31,6 +31,8 @@ import org.jclouds.domain.LocationScope;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.nova.v2_0.compute.options.NodeAndNovaTemplateOptions;
+import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaComputeServiceExpectTest;
import org.testng.annotations.Test;
@@ -55,7 +57,8 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
final NodeMetadata node = new NodeMetadataBuilder().id("az-1.region-a.geo-1/71592").providerId("71592").location(
host).name("Server 71592").status(Status.RUNNING).privateAddresses(ImmutableSet.of("10.4.27.237"))
.credentials(LoginCredentials.builder().password("foo").build()).build();
-
+ final NovaTemplateOptions options = NovaTemplateOptions.Builder.autoAssignFloatingIp(false);
+
HttpRequest createFloatingIP = HttpRequest.builder().method("POST").endpoint(
URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips")).headers(
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
@@ -77,9 +80,13 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
.getInstance(AllocateAndAddFloatingIpToNode.class);
AtomicReference<NodeMetadata> nodeRef = Atomics.newReference(node);
- fn.apply(nodeRef);
+ AtomicReference<NovaTemplateOptions> optionsRef = Atomics.newReference(options);
+ AtomicReference<NodeAndNovaTemplateOptions> nodeNovaRef = NodeAndNovaTemplateOptions.newAtomicReference(nodeRef, optionsRef);
+
+ fn.apply(nodeNovaRef);
NodeMetadata node1 = nodeRef.get();
assertNotNull(node1);
+ assertNotNull(optionsRef.get());
assertEquals(node1.getPublicAddresses(), ImmutableSet.of("10.0.0.3"));
assertEquals(node1.getCredentials(), node.getCredentials());
@@ -96,7 +103,7 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
return addFloatingIPRequest;
}
- public void testAllocateWhenAllocationFailsLookupUnusedIpAddToServerAndUpdatesNodeMetadata() throws Exception {
+ public void testAllocateWhenAllocationFailsOn400LookupUnusedIpAddToServerAndUpdatesNodeMetadata() throws Exception {
HttpResponse createFloatingIPResponse = HttpResponse
.builder()
.statusCode(400)
@@ -124,10 +131,51 @@ public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeSer
.getInstance(AllocateAndAddFloatingIpToNode.class);
AtomicReference<NodeMetadata> nodeRef = Atomics.newReference(node);
- fn.apply(nodeRef);
+ AtomicReference<NovaTemplateOptions> optionsRef = Atomics.newReference(options);
+ AtomicReference<NodeAndNovaTemplateOptions> nodeNovaRef = NodeAndNovaTemplateOptions.newAtomicReference(nodeRef, optionsRef);
+
+ fn.apply(nodeNovaRef);
NodeMetadata node1 = nodeRef.get();
assertNotNull(node1);
+ assertNotNull(optionsRef.get());
assertEquals(node1.getPublicAddresses(), ImmutableSet.of("10.0.0.5"));
+ }
+
+ public void testAllocateWhenAllocationFailsOn404LookupUnusedIpAddToServerAndUpdatesNodeMetadata() throws Exception {
+ HttpResponse createFloatingIPResponse = HttpResponse
+ .builder()
+ .statusCode(404)
+ .payload(
+ payloadFromStringWithContentType(
+ "{\"badRequest\": {\"message\": \"AddressLimitExceeded: Address quota exceeded. You cannot create any more addresses\", \"code\": 404}}",
+ "application/json")).build();
+
+ HttpRequest list = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-floating-ips")).headers(
+ ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
+ authToken).build()).build();
+
+ HttpResponse listResponseForUnassigned = HttpResponse.builder().statusCode(200).payload(
+ payloadFromResource("/floatingip_list.json")).build();
+
+ HttpRequest addFloatingIPRequest = addFloatingIPForAddress("10.0.0.5");
+
+ AllocateAndAddFloatingIpToNode fn = requestsSendResponses(
+ ImmutableMap.<HttpRequest, HttpResponse> builder().put(keystoneAuthWithUsernameAndPasswordAndTenantName,
+ responseWithKeystoneAccess).put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(
+ createFloatingIP, createFloatingIPResponse)
+ .put(addFloatingIPRequest, addFloatingIPResponse).put(list,
+ listResponseForUnassigned).build()).getContext().utils().injector()
+ .getInstance(AllocateAndAddFloatingIpToNode.class);
+
+ AtomicReference<NodeMetadata> nodeRef = Atomics.newReference(node);
+ AtomicReference<NovaTemplateOptions> optionsRef = Atomics.newReference(options);
+ AtomicReference<NodeAndNovaTemplateOptions> nodeNovaRef = NodeAndNovaTemplateOptions.newAtomicReference(nodeRef, optionsRef);
+ fn.apply(nodeNovaRef);
+ NodeMetadata node1 = nodeRef.get();
+ assertNotNull(node1);
+ assertNotNull(optionsRef.get());
+ assertEquals(node1.getPublicAddresses(), ImmutableSet.of("10.0.0.5"));
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7641bd61/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java b/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java
index e73a9e6..15db2b4 100644
--- a/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java
+++ b/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java
@@ -28,7 +28,11 @@ public class InsufficientResourcesException extends RuntimeException {
public InsufficientResourcesException() {
super();
}
-
+
+ public InsufficientResourcesException(String arg0) {
+ super(arg0);
+ }
+
public InsufficientResourcesException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
[2/2] git commit: Fixed version for hpcloud-blockstorage
Posted by na...@apache.org.
Fixed version for hpcloud-blockstorage
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/e94b878b
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/e94b878b
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/e94b878b
Branch: refs/heads/1.7.x
Commit: e94b878b28dd77195790010ce146c211d35e64d8
Parents: 7641bd6
Author: Ignasi Barrera <na...@apache.org>
Authored: Wed Jul 9 17:42:56 2014 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Jul 9 17:42:56 2014 +0200
----------------------------------------------------------------------
providers/hpcloud-blockstorage/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/e94b878b/providers/hpcloud-blockstorage/pom.xml
----------------------------------------------------------------------
diff --git a/providers/hpcloud-blockstorage/pom.xml b/providers/hpcloud-blockstorage/pom.xml
index 890ab3b..3b9c68d 100644
--- a/providers/hpcloud-blockstorage/pom.xml
+++ b/providers/hpcloud-blockstorage/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
- <version>1.8.0-SNAPSHOT</version>
+ <version>1.7.4-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.apache.jclouds.provider</groupId>