diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java b/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java index 36b6f85587..295ce3aa9d 100644 --- a/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java +++ b/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java @@ -18,28 +18,58 @@ */ package org.jclouds.compute.predicates; -import com.google.common.base.Predicate; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.util.Utils.checkNotEmpty; + +import java.util.Set; + +import javax.annotation.Nullable; + +import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeState; -import javax.annotation.Nullable; -import static org.jclouds.util.Utils.checkNotEmpty; +import com.google.common.base.Predicate; +import com.google.common.collect.Sets; /** * Container for node filters (predicates). - * + * * This class has static methods that create customized predicates to use with * {@link org.jclouds.compute.ComputeService}. - * + * * @author Oleksiy Yarmula */ public class NodePredicates { /** - * Return nodes with specified tag. - * Note: returns all nodes, regardless of the state. - * - * @param tag tag to match the items + * Return nodes with the specific ids Note: returns all nodes, regardless of the state. + * + * @param ids + * ids of the resources + * @return predicate + */ + public static Predicate withIds(String... ids) { + checkNotNull(ids, "ids must be defined"); + final Set search = Sets.newHashSet(ids); + return new Predicate() { + @Override + public boolean apply(@Nullable ComputeMetadata nodeMetadata) { + return search.contains(nodeMetadata.getId()); + } + + @Override + public String toString() { + return "withIds(" + search + ")"; + } + }; + } + + /** + * Return nodes with specified tag. Note: returns all nodes, regardless of the state. + * + * @param tag + * tag to match the items * @return predicate */ public static Predicate withTag(final String tag) { @@ -49,12 +79,19 @@ public class NodePredicates { public boolean apply(@Nullable NodeMetadata nodeMetadata) { return tag.equals(nodeMetadata.getTag()); } + + @Override + public String toString() { + return "withTag(" + tag + ")"; + } }; } /** * Return nodes with specified tag that are in the RUNNING state. - * @param tag tag to match the items + * + * @param tag + * tag to match the items * @return predicate */ public static Predicate activeWithTag(final String tag) { @@ -62,7 +99,13 @@ public class NodePredicates { return new Predicate() { @Override public boolean apply(@Nullable NodeMetadata nodeMetadata) { - return tag.equals(nodeMetadata.getTag()) && nodeMetadata.getState() == NodeState.RUNNING; + return tag.equals(nodeMetadata.getTag()) + && nodeMetadata.getState() == NodeState.RUNNING; + } + + @Override + public String toString() { + return "activeWithTag(" + tag + ")"; } }; } @@ -75,6 +118,11 @@ public class NodePredicates { public boolean apply(@Nullable NodeMetadata nodeMetadata) { return nodeMetadata.getState() == NodeState.RUNNING; } + + @Override + public String toString() { + return "ACTIVE"; + } }; /** @@ -85,6 +133,11 @@ public class NodePredicates { public boolean apply(@Nullable NodeMetadata nodeMetadata) { return nodeMetadata.getState() == NodeState.TERMINATED; } + + @Override + public String toString() { + return "TERMINATED"; + } }; } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java b/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java index 504855319d..19719edb1a 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptions.java @@ -76,7 +76,7 @@ public class InstantiateVAppTemplateOptions { } public InstantiateVAppTemplateOptions memory(long megabytes) { - checkArgument(megabytes % 512 == 0, "megabytes must be in an increment of 512"); + checkArgument(megabytes >= 1, "megabytes must be positive"); this.memorySizeMegabytes = megabytes + ""; return this; } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java index d22386bbc6..8bce8f3d8e 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/options/InstantiateVAppTemplateOptionsTest.java @@ -85,11 +85,6 @@ public class InstantiateVAppTemplateOptionsTest { assertEquals(options.getMemorySizeMegabytes(), "512"); } - @Test(expectedExceptions = IllegalArgumentException.class) - public void testRamStaticWrong() { - memory(511); - } - @Test public void testDisk() { InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions(); diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/domain/VAppConfiguration.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/domain/VAppConfiguration.java index 480374fda0..0cc6622b72 100644 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/domain/VAppConfiguration.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/domain/VAppConfiguration.java @@ -19,9 +19,9 @@ package org.jclouds.vcloud.terremark.domain; import static com.google.common.base.Preconditions.checkArgument; +import static org.jclouds.util.Utils.checkNotEmpty; import java.util.List; -import java.util.regex.Pattern; import com.google.common.collect.Lists; @@ -37,62 +37,41 @@ public class VAppConfiguration { private List disks = Lists.newArrayList(); private List disksToDelete = Lists.newArrayList(); - public static final Pattern NAME_PATTERN = Pattern.compile("^[a-zA-Z][-a-zA-Z0-9]+"); - /** - * The vApp name has the following requirements: Name can use uppercase and/or lowercase letters. - * Name can contain numbers or hyphens (-). Name may only begin with a letter. A maximum of 15 - * characters are allowed + * The vApp name * */ public VAppConfiguration changeNameTo(String name) { - checkArgument( - NAME_PATTERN.matcher(name).matches(), - "Name can use uppercase and/or lowercase letters, numbers or hyphens (-). Name may only begin with a letter."); - checkArgument(name.length() <= 15, "A maximum of 15 characters are allowed."); + checkNotEmpty(name, "name must be specified"); this.name = name; return this; } /** - * the number of virtual CPUs. You can set this to “1,” “2,” “4,” or “8.” + * the number of virtual CPUs. */ public VAppConfiguration changeProcessorCountTo(int cpus) { - checkArgument(cpus == 1 || cpus == 2 || cpus == 4 || cpus == 8, - "cpu count must be in 1,2,4,8"); + checkArgument(cpus >= 1, "cpu count must be positive"); this.processorCount = cpus; return this; } /** - * number of MB of memory. This should be either 512 or a multiple of 1024 (1 GB). + * number of MB of memory. */ public VAppConfiguration changeMemoryTo(long megabytes) { - checkArgument(megabytes == 512 || megabytes % 1024 == 0, - "memory must be 512 or an interval of 1024"); - checkArgument(megabytes <= 16384, "memory must be no more than 16GB"); + checkArgument(megabytes >= 1, "megabytes must be positive"); this.memory = megabytes; return this; } /** * To define a new disk, all you need to define is the size of the disk. The allowed values are a - * multiple of 1048576.
- * For example:
- * 1048576 (1 GB)
- * 2097152 (2 GB)
- * 3145728 (3 GB)
- * 4194304 (4 GB)
- * 5242880 (5 GB)
- * ...
- * 524288000 (500 GB)
- * You can have a total of 15 disks. Each disk can contain up to 500 GB of storage. + * multiple of 1048576. */ public VAppConfiguration addDisk(long kilobytes) { + checkArgument(kilobytes > 0, "kilobytes must be positive"); checkArgument(kilobytes % 1048576 == 0, "disk must be an interval of 1048576"); - checkArgument(kilobytes >= 25 *1048576, "disk must be at least 25GB"); - checkArgument(kilobytes <= 524288000, "disk must be no more than 500GB"); - checkArgument(disks.size() < 14, "you can only add up to 14 disks for a total of 15"); this.disks.add(kilobytes); return this; } diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClientTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClientTest.java index c17ee51542..26ce672eb0 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClientTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClientTest.java @@ -182,7 +182,7 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest httpMethod = processor.createRequest(method, "1", "name", 3 + "", TerremarkInstantiateVAppTemplateOptions.Builder.processorCount( - 1).memory(512).inRow("row").inGroup("group").withPassword("password") + 2).memory(512).inRow("row").inGroup("group").withPassword("password") .inNetwork(URI.create("http://network"))); assertRequestLineEquals(httpMethod, diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java index 81a832749a..9e8f3e8f31 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudClientLiveTest.java @@ -71,6 +71,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.inject.Injector; @@ -176,7 +177,15 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest { // determine the cheapest configuration size SortedSet sizeOptions = tmClient.getComputeOptionsOfCatalogItem(itemId); - ComputeOptions cheapestOption = sizeOptions.first(); + + ComputeOptions cheapestOption = Iterables.find(sizeOptions, new Predicate() { + + @Override + public boolean apply(ComputeOptions arg0) { + return arg0.getProcessorCount() == 2; + } + + }); // create an options object to collect the configuration we want. TerremarkInstantiateVAppTemplateOptions instantiateOptions = processorCount( @@ -363,8 +372,8 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest { vApp = tmClient.getVApp(vApp.getId()); - Task task = tmClient.configureVApp(vApp, changeNameTo("eduardo").changeMemoryTo(1024) - .changeProcessorCountTo(2).addDisk(25 * 1048576).addDisk(25 * 1048576)); + Task task = tmClient.configureVApp(vApp, changeNameTo("eduardo").changeMemoryTo(1536) + .changeProcessorCountTo(1).addDisk(25 * 1048576).addDisk(25 * 1048576)); assert successTester.apply(task.getId()); @@ -373,14 +382,14 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest { assertEquals( Iterables.getOnlyElement( vApp.getResourceAllocationByType().get(ResourceType.PROCESSOR)) - .getVirtualQuantity(), 2); + .getVirtualQuantity(), 1); assertEquals(Iterables.getOnlyElement( vApp.getResourceAllocationByType().get(ResourceType.MEMORY)).getVirtualQuantity(), - 1024); + 1536); assertEquals(vApp.getResourceAllocationByType().get(ResourceType.DISK_DRIVE).size(), 3); assert successTester.apply(tmClient.powerOnVApp(vApp.getId()).getId()); - + loopAndCheckPass(); assert successTester.apply(tmClient.powerOffVApp(vApp.getId()).getId()); @@ -473,8 +482,8 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest { account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); Injector injector = new TerremarkVCloudContextBuilder("terremark", - new TerremarkVCloudPropertiesBuilder( account, key).build()).withModules(new Log4JLoggingModule(), - new JschSshClientModule()).buildInjector(); + new TerremarkVCloudPropertiesBuilder(account, key).build()).withModules( + new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); connection = tmClient = injector.getInstance(TerremarkVCloudClient.class); diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/BindVAppConfigurationToXmlPayloadTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/BindVAppConfigurationToXmlPayloadTest.java index 3d958877f1..2f0ff960c4 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/BindVAppConfigurationToXmlPayloadTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/BindVAppConfigurationToXmlPayloadTest.java @@ -69,9 +69,8 @@ public class BindVAppConfigurationToXmlPayloadTest { }); public void testChangeName() throws IOException { - VAppImpl vApp = new VAppImpl("4213", "MyAppServer6", - URI - .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), + VAppImpl vApp = new VAppImpl("4213", "MyAppServer6", URI + .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), VAppStatus.OFF, 4194304l, null, ImmutableListMultimap. of(), null, null, ImmutableSortedSet.of(new ResourceAllocation(1, "n/a", null, ResourceType.PROCESSOR, null, null, null, null, null, null, 2, null), @@ -85,7 +84,9 @@ public class BindVAppConfigurationToXmlPayloadTest { "roberto"); Multimap headers = Multimaps.synchronizedMultimap(HashMultimap . create()); + VAppConfiguration config = new VAppConfiguration().changeNameTo("roberto"); + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); expect(request.getArgs()).andReturn(new Object[] { vApp, config }).atLeastOnce(); @@ -103,25 +104,94 @@ public class BindVAppConfigurationToXmlPayloadTest { } public void testRemoveDisk() throws IOException { - VAppImpl vApp = new VAppImpl("4213", "MyAppServer6", - URI - .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), + VAppImpl vApp = new VAppImpl("4213", "MyAppServer6", URI + .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), VAppStatus.OFF, 4194304l, null, ImmutableListMultimap. of(), null, null, ImmutableSortedSet.of(new ResourceAllocation(1, "n/a", null, ResourceType.PROCESSOR, null, null, null, null, null, null, 2, null), new ResourceAllocation(2, "n/a", null, ResourceType.MEMORY, null, null, null, null, null, null, 1024, null), new ResourceAllocation(9, "n/a", null, ResourceType.DISK_DRIVE, null, "1048576", null, 0, - null, null, 209152, null),new ResourceAllocation(9, - "n/a", null, ResourceType.DISK_DRIVE, null, "1048576", null, 1, - null, null, 209152, null))); + null, null, 209152, null), new ResourceAllocation(9, "n/a", null, + ResourceType.DISK_DRIVE, null, "1048576", null, 1, null, null, + 209152, null))); String expected = Utils.toStringAndClose( getClass().getResourceAsStream("/terremark/configureVApp.xml")).replace("eduardo", "MyAppServer6"); Multimap headers = Multimaps.synchronizedMultimap(HashMultimap . create()); + VAppConfiguration config = new VAppConfiguration().deleteDiskWithAddressOnParent(1); + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + expect(request.getArgs()).andReturn(new Object[] { vApp, config }).atLeastOnce(); + expect(request.getFirstHeaderOrNull("Content-Type")).andReturn(null).atLeastOnce(); + expect(request.getHeaders()).andReturn(headers).atLeastOnce(); + request.setPayload(expected); + replay(request); + + BindVAppConfigurationToXmlPayload binder = injector + .getInstance(BindVAppConfigurationToXmlPayload.class); + + Map map = Maps.newHashMap(); + binder.bindToRequest(request, map); + verify(request); + } + + public void testChangeCPUCountTo4() throws IOException { + VAppImpl vApp = new VAppImpl("4213", "eduardo", URI + .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), + VAppStatus.OFF, 4194304l, null, ImmutableListMultimap. of(), + null, null, ImmutableSortedSet.of(new ResourceAllocation(1, "n/a", null, + ResourceType.PROCESSOR, null, null, null, null, null, null, 4, null), + new ResourceAllocation(2, "n/a", null, ResourceType.MEMORY, null, null, + null, null, null, null, 1024, null), new ResourceAllocation(9, + "n/a", null, ResourceType.DISK_DRIVE, null, "1048576", null, 0, + null, null, 209152, null))); + String expected = Utils.toStringAndClose(getClass().getResourceAsStream( + "/terremark/configureVApp4.xml")); + Multimap headers = Multimaps.synchronizedMultimap(HashMultimap + . create()); + + VAppConfiguration config = new VAppConfiguration().changeProcessorCountTo(4); + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + expect(request.getArgs()).andReturn(new Object[] { vApp, config }).atLeastOnce(); + expect(request.getFirstHeaderOrNull("Content-Type")).andReturn(null).atLeastOnce(); + expect(request.getHeaders()).andReturn(headers).atLeastOnce(); + request.setPayload(expected); + replay(request); + + BindVAppConfigurationToXmlPayload binder = injector + .getInstance(BindVAppConfigurationToXmlPayload.class); + + Map map = Maps.newHashMap(); + binder.bindToRequest(request, map); + verify(request); + } + + public void testChangeMemoryTo1536() throws IOException { + VAppImpl vApp = new VAppImpl("4213", "MyAppServer6", URI + .create("https://services.vcloudexpress/terremark.com/api/v0.8/vapp/4213"), + VAppStatus.OFF, 4194304l, null, ImmutableListMultimap. of(), + null, null, ImmutableSortedSet.of(new ResourceAllocation(1, "n/a", null, + ResourceType.PROCESSOR, null, null, null, null, null, null, 2, null), + new ResourceAllocation(2, "n/a", null, ResourceType.MEMORY, null, null, + null, null, null, null, 1536, null), new ResourceAllocation(9, + "n/a", null, ResourceType.DISK_DRIVE, null, "1048576", null, 0, + null, null, 209152, null))); + + String expected = Utils.toStringAndClose( + getClass().getResourceAsStream("/terremark/configureVApp.xml")).replace("eduardo", + "MyAppServer6").replace("1024", "1536"); + Multimap headers = Multimaps.synchronizedMultimap(HashMultimap + . create()); + + VAppConfiguration config = new VAppConfiguration().changeMemoryTo(1536); + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); expect(request.getArgs()).andReturn(new Object[] { vApp, config }).atLeastOnce(); @@ -137,5 +207,4 @@ public class BindVAppConfigurationToXmlPayloadTest { binder.bindToRequest(request, map); verify(request); } - } diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/TerremarkBindInstantiateVAppTemplateParamsToXmlPayloadTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/TerremarkBindInstantiateVAppTemplateParamsToXmlPayloadTest.java index 7e042762ab..8ea516d02e 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/TerremarkBindInstantiateVAppTemplateParamsToXmlPayloadTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/binders/TerremarkBindInstantiateVAppTemplateParamsToXmlPayloadTest.java @@ -75,7 +75,7 @@ public class TerremarkBindInstantiateVAppTemplateParamsToXmlPayloadTest { GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); expect(request.getArgs()).andReturn( - new Object[] { TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(1) + new Object[] { TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(2) .memory(512).inRow("row").inGroup("group").withPassword( "password").inNetwork(URI.create("http://network")) }) .atLeastOnce(); diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/options/TerremarkInstantiateVAppTemplateOptionsTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/options/TerremarkInstantiateVAppTemplateOptionsTest.java index 0094fb88d5..37c0049f1e 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/options/TerremarkInstantiateVAppTemplateOptionsTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/options/TerremarkInstantiateVAppTemplateOptionsTest.java @@ -122,11 +122,6 @@ public class TerremarkInstantiateVAppTemplateOptionsTest { assertEquals(options.getMemorySizeMegabytes(), "512"); } - @Test(expectedExceptions = IllegalArgumentException.class) - public void testMegabytesStaticWrong() { - memory(511); - } - @Test(expectedExceptions = IllegalArgumentException.class) public void testDiskSizeKilobytes() { TerremarkInstantiateVAppTemplateOptions options = new TerremarkInstantiateVAppTemplateOptions(); diff --git a/vcloud/terremark/src/test/resources/terremark/InstantiateVAppTemplateParams-options-test.xml b/vcloud/terremark/src/test/resources/terremark/InstantiateVAppTemplateParams-options-test.xml index f9b267cbc3..b445cd77d8 100644 --- a/vcloud/terremark/src/test/resources/terremark/InstantiateVAppTemplateParams-options-test.xml +++ b/vcloud/terremark/src/test/resources/terremark/InstantiateVAppTemplateParams-options-test.xml @@ -1 +1 @@ -13124512allowInOutfalse \ No newline at end of file +13224512allowInOutfalse \ No newline at end of file diff --git a/vcloud/terremark/src/test/resources/terremark/configureVApp4.xml b/vcloud/terremark/src/test/resources/terremark/configureVApp4.xml new file mode 100644 index 0000000000..6ffd22591a --- /dev/null +++ b/vcloud/terremark/src/test/resources/terremark/configureVApp4.xml @@ -0,0 +1 @@ +
Virtual Hardware13424102401048576917209152
\ No newline at end of file