From f22ac3bffa7e355ab71ca9f2f79c823a627a8ae1 Mon Sep 17 00:00:00 2001 From: Kedar Dave Date: Wed, 27 Apr 2011 18:01:41 -0500 Subject: [PATCH 1/3] implemented add/delete firewall rule for savvis-symphonyvpdc --- .../binders/BindFirewallRuleToXmlPayload.java | 121 ++++++++++++++++++ .../vpdc/features/FirewallAsyncClient.java | 40 +++++- .../savvis/vpdc/features/FirewallClient.java | 29 ++++- .../BindFirewallRuleToXmlPayloadTest.java | 45 +++++++ .../vpdc/features/BaseVPDCClientLiveTest.java | 2 +- .../vpdc/features/FirewallClientLiveTest.java | 82 +++++++++++- .../resources/firewallService-default.xml | 1 + 7 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayload.java create mode 100644 providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayloadTest.java create mode 100644 providers/savvis-symphonyvpdc/src/test/resources/firewallService-default.xml diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayload.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayload.java new file mode 100644 index 0000000000..92aed4ec58 --- /dev/null +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayload.java @@ -0,0 +1,121 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.savvis.vpdc.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Properties; + +import javax.inject.Singleton; +import javax.ws.rs.core.MediaType; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.binders.BindToStringPayload; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.savvis.vpdc.domain.FirewallRule; + +import com.jamesmurty.utils.XMLBuilder; + +/** + * + * @author Kedar Dave + * + */ +@Singleton +public class BindFirewallRuleToXmlPayload extends BindToStringPayload implements MapBinder { + @Override + public R bindToRequest(R request, Object toBind) { + throw new IllegalStateException("BindFirewallRuleToXmlPayload needs parameters"); + + } + + protected FirewallRule findRuleInArgsOrNull(GeneratedHttpRequest gRequest) { + for (Object arg : gRequest.getArgs()) { + if (arg instanceof FirewallRule) { + return (FirewallRule) arg; + } else if (arg instanceof FirewallRule[]) { + FirewallRule[] rules = (FirewallRule[]) arg; + return (rules.length > 0) ? rules[0] : null; + } + } + return null; + } + + @Override + public R bindToRequest(R request, Map postParams) { + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + "this binder is only valid for GeneratedHttpRequests!"); + GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; + checkState(gRequest.getArgs() != null, "args should be initialized at this point"); + + request = super.bindToRequest(request, + generateXml(findRuleInArgsOrNull(gRequest))); + request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_XML); + return request; + } + + public String generateXml(FirewallRule firewallRule) { + checkNotNull(firewallRule, "FirewallRule"); + + try { + XMLBuilder rootBuilder = buildRoot(); + addFirewallRuleSection(rootBuilder, firewallRule); + Properties outputProperties = new Properties(); + outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); + return rootBuilder.asString(outputProperties); + } catch (Exception e) { + return null; + } + } + + void addFirewallRuleSection(XMLBuilder rootBuilder, FirewallRule firewallRule) { + XMLBuilder firewallRuleBuilder = rootBuilder.e("svvs:FirewallRule"); + firewallRuleBuilder.e("svvs:IsEnabled").t(firewallRule.isEnabled() ? "true" : "false"); + firewallRuleBuilder.e("svvs:Description").t("Server Tier Firewall Rule"); + firewallRuleBuilder.e("svvs:Type").t(firewallRule.getFirewallType()); + firewallRuleBuilder.e("svvs:Log").t(firewallRule.isLogged() ? "yes" : "no"); + firewallRuleBuilder.e("svvs:Policy").t(firewallRule.getPolicy()); + firewallRuleBuilder.e("svvs:Protocols").e("svvs:"+firewallRule.getProtocol()).t("true").up().up(); + firewallRuleBuilder.e("svvs:Port").t(firewallRule.getPort()); + firewallRuleBuilder.e("svvs:Destination").t(firewallRule.getDestination()); + firewallRuleBuilder.e("svvs:Source").t(firewallRule.getSource()); + } + + protected XMLBuilder buildRoot() throws ParserConfigurationException, FactoryConfigurationError { + XMLBuilder rootBuilder = XMLBuilder.create("svvs:FirewallService") + .a("xmlns:common", "http://schemas.dmtf.org/wbem/wscim/1/common") + .a("xmlns:vApp", "http://www.vmware.com/vcloud/v0.8") + .a("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData") + .a("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData") + .a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1") + .a("xmlns:svvs", "http://schemas.api.sandbox.symphonyVPDC.savvis.net/vpdci"); + return rootBuilder; + } + + protected String ifNullDefaultTo(String value, String defaultValue) { + return value != null ? value : checkNotNull(defaultValue, "defaultValue"); + } + +} diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClient.java index 8920b4f85e..ee44b53e55 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClient.java @@ -18,10 +18,27 @@ */ package org.jclouds.savvis.vpdc.features; +import javax.annotation.Nullable; +import javax.ws.rs.DELETE; +import javax.ws.rs.PUT; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.ParamParser; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.savvis.vpdc.binders.BindFirewallRuleToXmlPayload; +import org.jclouds.savvis.vpdc.domain.FirewallRule; +import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie; +import org.jclouds.savvis.vpdc.functions.DefaultOrgIfNull; +import org.jclouds.savvis.vpdc.xml.TaskHandler; + +import com.google.common.util.concurrent.ListenableFuture; /** * Provides access to Symphony VPDC resources via their REST API. @@ -31,8 +48,29 @@ import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie; * @author Adrian Cole */ @RequestFilters(SetVCloudTokenCookie.class) -@Path("v{jclouds.api-version}") public interface FirewallAsyncClient { + /** + * @see FirewallClient#addFirewallRule + */ + @PUT + @XMLResponseParser(TaskHandler.class) + @Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/FirewallService/") + @MapBinder(BindFirewallRuleToXmlPayload.class) + ListenableFuture addFirewallRule( + @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, + @PathParam("vpdcId") String vpdcId, @PayloadParam("firewallRule") FirewallRule firewallRule); + + /** + * @see FirewallClient#deleteFirewallRule + */ + @DELETE + @XMLResponseParser(TaskHandler.class) + @Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/FirewallService/") + @MapBinder(BindFirewallRuleToXmlPayload.class) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture deleteFirewallRule( + @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, + @PathParam("vpdcId") String vpdcId, @PayloadParam("firewallRule") FirewallRule firewallRule); } diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallClient.java index c681918a7b..da26f301f6 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/FirewallClient.java @@ -21,6 +21,8 @@ package org.jclouds.savvis.vpdc.features; import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; +import org.jclouds.savvis.vpdc.domain.FirewallRule; +import org.jclouds.savvis.vpdc.domain.Task; /** * Provides access to Symphony VPDC resources via their REST API. @@ -31,5 +33,30 @@ import org.jclouds.concurrent.Timeout; */ @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) public interface FirewallClient { - + + /** + * Add a new firewall rule + * + * @param billingSiteId + * billing site Id, or null for default + * @param vpdcId + * vpdc Id + * @param firewallRule + * firewall rule to be added + * @return + */ + Task addFirewallRule(String billingSiteId, String vpdcId, FirewallRule firewallRule); + + /** + * Delete a firewall rule + * + * @param billingSiteId + * billing site Id, or null for default + * @param vpdcId + * vpdc Id + * @param firewallRule + * firewall rule to be deleted + * @return + */ + Task deleteFirewallRule(String billingSiteId, String vpdcId, FirewallRule firewallRule); } \ No newline at end of file diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayloadTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayloadTest.java new file mode 100644 index 0000000000..a3d245ae03 --- /dev/null +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindFirewallRuleToXmlPayloadTest.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.savvis.vpdc.binders; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.savvis.vpdc.domain.FirewallRule; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code BindVMSpecToXmlPayload} + * + * @author Kedar Dave + */ +@Test(groups = "unit") +public class BindFirewallRuleToXmlPayloadTest { + + public void test() throws IOException { + String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml")); + + FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") + .destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build(); + + assertEquals(new BindFirewallRuleToXmlPayload().generateXml(firewallRule), expected); + } +} diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java index d33a359a24..4bf96cd284 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java @@ -89,7 +89,7 @@ public class BaseVPDCClientLiveTest { context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of( new Log4JLoggingModule(), new JschSshClientModule()), overrides); restContext = context.getProviderSpecificContext(); - taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 650, 10, TimeUnit.SECONDS); + taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 1200, 10, TimeUnit.SECONDS); } @AfterGroups(groups = "live") diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java index f9054cbe0c..f30cca5ec8 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java @@ -18,14 +18,25 @@ */ package org.jclouds.savvis.vpdc.features; +import java.util.concurrent.TimeUnit; + +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.savvis.vpdc.domain.FirewallRule; +import org.jclouds.savvis.vpdc.domain.Resource; +import org.jclouds.savvis.vpdc.domain.Task; +import org.jclouds.savvis.vpdc.predicates.TaskSuccess; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; -@Test(groups = "live") +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + public class FirewallClientLiveTest extends BaseVPDCClientLiveTest { private FirewallClient client; + private String billingSiteId; + private String vpdcId; @Override @BeforeGroups(groups = { "live" }) @@ -33,7 +44,76 @@ public class FirewallClientLiveTest extends BaseVPDCClientLiveTest { super.setupClient(); client = restContext.getApi().getFirewallClient(); } + + @Test(groups = "live") + public void testAddFirewallRule() throws Exception { + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); + + String networkTierName = Iterables.get( + restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0) + .getName(); + + FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") + .destination(networkTierName).port("10000").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build(); + + System.out.printf("adding firewall rule:%s %n", firewallRule.toString()); + + Task task = client.addFirewallRule(billingSiteId, vpdcId, firewallRule); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES); + assert this.taskTester.apply(task.getId()); + } + + @Test(groups = "live", dependsOnMethods = {"testAddFirewallRule"}) + public void testDeleteFirewallRule() throws Exception { + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); + + String networkTierName = Iterables.get( + restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0) + .getName(); + + FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") + .destination(networkTierName).port("10000").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build(); + + System.out.printf("deleting firewall rule:%s %n", firewallRule.toString()); + + Task task = client.deleteFirewallRule(billingSiteId, vpdcId, firewallRule); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES); + assert this.taskTester.apply(task.getId()); + } @AfterGroups(groups = "live") protected void tearDown() { diff --git a/providers/savvis-symphonyvpdc/src/test/resources/firewallService-default.xml b/providers/savvis-symphonyvpdc/src/test/resources/firewallService-default.xml new file mode 100644 index 0000000000..5a0e642ced --- /dev/null +++ b/providers/savvis-symphonyvpdc/src/test/resources/firewallService-default.xml @@ -0,0 +1 @@ +trueServer Tier Firewall RuleSERVER_TIER_FIREWALLnoallowtrue22VM Tier01internet \ No newline at end of file From 44b0eefd870bbf8906e532e7b32e63b1a3aa96fa Mon Sep 17 00:00:00 2001 From: Kedar Dave Date: Thu, 28 Apr 2011 09:21:27 -0500 Subject: [PATCH 2/3] cleanup --- .../jclouds/savvis/vpdc/features/FirewallClientLiveTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java index f30cca5ec8..a8a645b8f7 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java @@ -76,7 +76,7 @@ public class FirewallClientLiveTest extends BaseVPDCClientLiveTest { // make sure there's no error assert task.getId() != null && task.getError() == null : task; - taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES); + assert this.taskTester.apply(task.getId()); } @@ -111,7 +111,7 @@ public class FirewallClientLiveTest extends BaseVPDCClientLiveTest { // make sure there's no error assert task.getId() != null && task.getError() == null : task; - taskTester = new RetryablePredicate(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES); + assert this.taskTester.apply(task.getId()); } From 6c370f558de0831e6f08e4d29626b570ef53a96e Mon Sep 17 00:00:00 2001 From: Kedar Dave Date: Thu, 28 Apr 2011 16:32:54 -0500 Subject: [PATCH 3/3] implemented poweroff, poweron for vm's, added missing tests for firewall operations. --- .../savvis/vpdc/features/VMAsyncClient.java | 19 ++++ .../savvis/vpdc/features/VMClient.java | 18 ++++ .../features/FirewallAsyncClientTest.java | 41 +++++++++ .../vpdc/features/FirewallClientLiveTest.java | 4 - .../vpdc/features/VMAsyncClientTest.java | 34 +++++++ .../vpdc/features/VMClientLiveTest.java | 88 ++++++++++++++++++- 6 files changed, 199 insertions(+), 5 deletions(-) diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java index a72703462b..e060dbf8e4 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java @@ -23,6 +23,7 @@ import java.net.URI; import javax.annotation.Nullable; import javax.ws.rs.DELETE; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -93,4 +94,22 @@ public interface VMAsyncClient { @XMLResponseParser(TaskHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture removeVM(@EndpointParam URI vm); + + /** + * @see VMClient#powerOffVM + */ + @POST + @XMLResponseParser(TaskHandler.class) + @Path("action/powerOff") + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture powerOffVM(@EndpointParam URI vm); + + /** + * @see VMClient#powerOnVM + */ + @POST + @XMLResponseParser(TaskHandler.class) + @Path("action/powerOn") + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture powerOnVM(@EndpointParam URI vm); } diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java index 2cf5724cf2..57e9549b1a 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java @@ -89,4 +89,22 @@ public interface VMClient { * @see #removeVMFromVDC */ Task removeVM(URI vm); + + /** + * Power off a VM + * + * @param vm + * href of the vm + * @return + */ + Task powerOffVM(URI vm); + + /** + * Power on a VM + * + * @param vm + * href of the vm + * @return + */ + Task powerOnVM(URI vm); } diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java index 8391a796cd..764ce18ab9 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java @@ -18,7 +18,16 @@ */ package org.jclouds.savvis.vpdc.features; +import java.io.IOException; +import java.lang.reflect.Method; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.savvis.vpdc.domain.FirewallRule; +import org.jclouds.savvis.vpdc.xml.TaskHandler; +import org.jclouds.util.Strings2; import org.testng.annotations.Test; import com.google.inject.TypeLiteral; @@ -31,6 +40,38 @@ import com.google.inject.TypeLiteral; @Test(groups = "unit") public class FirewallAsyncClientTest extends BaseVPDCAsyncClientTest { + public void testAddFirewallRule() throws NoSuchMethodException, IOException{ + Method method = FirewallAsyncClient.class.getMethod("addFirewallRule", String.class, String.class, FirewallRule.class); + HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") + .destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); + + assertRequestLineEquals(request, "PUT https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/FirewallService/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml")), + "application/xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + + checkFilters(request); + } + + public void testDeleteFirewallRule() throws NoSuchMethodException, IOException{ + Method method = FirewallAsyncClient.class.getMethod("deleteFirewallRule", String.class, String.class, FirewallRule.class); + HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") + .destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); + + assertRequestLineEquals(request, "DELETE https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/FirewallService/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml")), + "application/xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(request); + } @Override protected TypeLiteral> createTypeLiteral() { diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java index a8a645b8f7..14bb39307e 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallClientLiveTest.java @@ -18,13 +18,9 @@ */ package org.jclouds.savvis.vpdc.features; -import java.util.concurrent.TimeUnit; - -import org.jclouds.predicates.RetryablePredicate; import org.jclouds.savvis.vpdc.domain.FirewallRule; import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Task; -import org.jclouds.savvis.vpdc.predicates.TaskSuccess; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java index e8890bf6dd..7542ef1801 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java @@ -141,6 +141,40 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { checkFilters(request); } + + public void testPowerOffVM() throws SecurityException, NoSuchMethodException, IOException { + Method method = VMAsyncClient.class.getMethod("powerOffVM", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33")); + + assertRequestLineEquals(request, + "POST https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33/action/powerOff HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, null, null, false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testPowerOnVM() throws SecurityException, NoSuchMethodException, IOException { + Method method = VMAsyncClient.class.getMethod("powerOnVM", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33")); + + assertRequestLineEquals(request, + "POST https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33/action/powerOn HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, null, null, false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(request); + } @Override protected TypeLiteral> createTypeLiteral() { diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java index ed22798413..3b7a37ca54 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java @@ -21,6 +21,7 @@ package org.jclouds.savvis.vpdc.features; import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; +import java.net.URI; import java.util.concurrent.TimeUnit; import org.jclouds.cim.OSType; @@ -34,7 +35,10 @@ import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.domain.VDC; import org.jclouds.savvis.vpdc.domain.VM; +import org.jclouds.savvis.vpdc.domain.VM.Status; import org.jclouds.savvis.vpdc.domain.VMSpec; +import org.jclouds.savvis.vpdc.options.GetVMOptions; +import org.jclouds.savvis.vpdc.reference.VCloudMediaType; import org.jclouds.ssh.SshClient; import org.jclouds.util.InetAddresses2; import org.testng.annotations.AfterGroups; @@ -114,7 +118,7 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { .operatingSystem(os).memoryInGig(2).addDataDrive("/data01", 25).build()); // make sure there's no error - assert task.getId() != null && task.getError() != null : task; + assert task.getId() != null && task.getError() == null : task; assert this.taskTester.apply(task.getId()); vm = restContext.getApi().getBrowsingClient().getVMInVDC(billingSiteId, vpdcId, task.getOwner().getId()); @@ -148,6 +152,88 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { } } + public void testPowerOffVM() throws Exception { + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); + + VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); + URI vmURI = Iterables.find(vpdc.getResourceEntities(), new Predicate() { + @Override + public boolean apply(Resource arg0) { + if(VCloudMediaType.VAPP_XML.equals(arg0.getType())){ + VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); + System.out.printf("powering off vm - %s%n", response1.getName()); + if(response1.getStatus().equals(Status.ON)){ + return true; + } + } + return false; + } + + }).getHref(); + + Task task = client.powerOffVM(vmURI); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + + assert this.taskTester.apply(task.getId()); + } + + public void testPowerOnVM() throws Exception { + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); + + VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); + URI vmURI = Iterables.find(vpdc.getResourceEntities(), new Predicate() { + @Override + public boolean apply(Resource arg0) { + if(VCloudMediaType.VAPP_XML.equals(arg0.getType())){ + VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); + System.out.printf("powering on vm - %s%n", response1.getName()); + if(response1.getStatus().equals(Status.OFF)){ + return true; + } + } + return false; + } + + }).getHref(); + + Task task = client.powerOnVM(vmURI); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + + assert this.taskTester.apply(task.getId()); + } + @AfterGroups(groups = "live") protected void tearDown() { if (vm != null) {