Issue 695: InternetService: GET and EDIT internet service

This commit is contained in:
Jason King 2011-12-20 17:17:31 +00:00
parent 0d5ccf2af5
commit 2cb4c4ac76
8 changed files with 390 additions and 10 deletions

View File

@ -0,0 +1,122 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.binders;
import com.jamesmurty.utils.XMLBuilder;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.tmrk.enterprisecloud.domain.NamedResource;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetServicePersistenceType;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.util.Properties;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* For use with {@see VirtualMachineClient#createVirtualMachineFromTemplate}
* @author Jason King
*/
@Singleton
public class BindInternetServiceToXmlPayload implements Binder {
private final BindToStringPayload stringBinder;
@Inject
BindInternetServiceToXmlPayload(BindToStringPayload stringBinder) {
this.stringBinder = stringBinder;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object key) {
checkArgument(checkNotNull(key, "key") instanceof InternetService, "this binder is only valid for InternetService instances");
checkNotNull(request, "request");
InternetService data = InternetService.class.cast(key);
String payload = createXMLPayload(data);
return stringBinder.bindToRequest(request, payload);
}
private String createXMLPayload(InternetService data) {
try {
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
final String name = checkNotNull(data.getName(), "name");
final String enabled = Boolean.toString(data.isEnabled());
final String description = data.getDescription();
final InternetServicePersistenceType persistence = data.getPersistence();
final String redirectUrl = data.getRedirectUrl();
final NamedResource trustedNetworkGroup = data.getTrustedNetworkGroup();
final NamedResource backupInternetService = data.getBackupInternetService();
XMLBuilder builder = XMLBuilder.create("InternetService").a("name", name)
.e("Enabled").t(enabled).up();
if(description!=null) {
builder = builder.e("Description").t(description).up();
}
builder = persistence(builder,persistence);
if(redirectUrl!=null) {
builder = builder.e("RedirectUrl").t(redirectUrl);
}
if(trustedNetworkGroup!=null) {
final String href = trustedNetworkGroup.getHref().toString();
String groupName = trustedNetworkGroup.getName();
String type = trustedNetworkGroup.getType();
builder = builder.e("TrustedNetworkGroup").a("href",href).a("name",groupName).a("type", type).up();
}
if(backupInternetService!=null) {
final String href = backupInternetService.getHref().toString();
String groupName = backupInternetService.getName();
String type = backupInternetService.getType();
builder = builder.e("BackupInternetService").a("href",href).a("name",groupName).a("type",type).up();
}
return builder.asString(outputProperties);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (TransformerException t) {
throw new RuntimeException(t);
}
}
private XMLBuilder persistence(XMLBuilder in, InternetServicePersistenceType persistenceType) {
checkNotNull(persistenceType,"persistenceType");
final InternetServicePersistenceType.PersistenceType type = persistenceType.getPersistenceType();
final int timeout = persistenceType.getTimeout();
in = in.e("Persistence").e("Type").t(type.value()).up();
if(!type.equals(InternetServicePersistenceType.PersistenceType.NONE) && timeout > -1 ) {
in = in.e("Timeout").t(Integer.toString(timeout)).up();
}
return in.up();
}
}

View File

@ -24,8 +24,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.CaseFormat.*;
/**
* <xs:complexType name="InternetServiceType">
@ -43,7 +42,8 @@ public class InternetServicePersistenceType {
SOURCE_IP;
public String value() {
return UPPER_UNDERSCORE.to(LOWER_CAMEL, name());
String lower = UPPER_UNDERSCORE.to(LOWER_CAMEL,name());
return LOWER_CAMEL.to(UPPER_CAMEL,lower);
}
}
@ -59,7 +59,7 @@ public class InternetServicePersistenceType {
public static class Builder {
private PersistenceType persistenceType;
private int timeout;
private int timeout = -1;
/**
* @see org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetServicePersistenceType#getPersistenceType
@ -99,7 +99,7 @@ public class InternetServicePersistenceType {
private PersistenceType persistenceType;
@XmlElement(name = "Timeout")
private int timeout;
private int timeout = -1;
public PersistenceType getPersistenceType() {
return persistenceType;

View File

@ -22,10 +22,13 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.*;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.tmrk.enterprisecloud.domain.Task;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import org.jclouds.tmrk.enterprisecloud.functions.URISource;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import java.net.URI;
/**
@ -50,4 +53,13 @@ public interface InternetServiceAsyncClient {
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<InternetService> getInternetService(@EndpointParam URI uri);
/**
* @see org.jclouds.tmrk.enterprisecloud.features.InternetServiceClient#editInternetService
*/
@PUT
@Consumes("application/vnd.tmrk.cloud.internetService")
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Task> editInternetService(@EndpointParam(parser = URISource.GetURI.class) InternetService internetService);
}

View File

@ -19,6 +19,7 @@
package org.jclouds.tmrk.enterprisecloud.features;
import org.jclouds.concurrent.Timeout;
import org.jclouds.tmrk.enterprisecloud.domain.Task;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import java.net.URI;
@ -45,4 +46,33 @@ public interface InternetServiceClient {
* @return the internet service
*/
InternetService getInternetService(URI uri);
/**
* The editInternetService call edits the name, enablement, description, persistence,
* redirect URL, trusted network group, or backup Internet service
* on a specified Internet service in an environment.
* If successful, the call returns the task that modified the Internet service.
*
* The name property on InternetService is required and may be changed.
* Note: The name may not be changed to that of another Internet service.
* Port is optional and ignored if present.
* Enabled is required.
* Persistence Type refers to the method for persisting a connection session.
* e.g. SourceIp use the IP address of the source device for persistence.
* If Timeout is absent with Type=SourceIp, then Timeout defaults to 2 minutes.
* Omit Timeout if Type=none.
* Note: The minimum value for Timeout is 2 (for two minutes) and the maximum is 5.
* Both TrustedNetworkGroup and BackupInternetService are optional.
* Including a TrustedNetworkGroup or BackupInternetService not currently on the Internet service
* adds that trusted network group or backup Internet service to the Internet service.
* Note: If any TrustedNetworkGroup is valued on the Internet service and not present in the call,
* that trusted network group is removed from the Internet service.
* Similarly, if any BackupInternetService is valued on the Internet service and not present in the call,
* that backup Internet service is removed from the Internet service.
*
* @param service the internet service to edit
* @return the Task representing the create action
*/
Task editInternetService(InternetService service);
}

View File

@ -0,0 +1,169 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.tmrk.enterprisecloud.binders;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.http.HttpRequest;
import org.jclouds.tmrk.enterprisecloud.domain.NamedResource;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetServicePersistenceType;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URI;
import static org.testng.Assert.assertEquals;
/**
* Tests behavior of {@code BindInternetServiceToXmlPayload}
* @author Jason King
*/
@Test(groups = "unit", testName = "BindInternetServiceToXmlPayloadTest")
public class BindInternetServiceToXmlPayloadTest {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
}
});
public void testPayloadMinimalXmlContent() throws IOException {
String expected =
"<InternetService name='testName'>" +
"<Enabled>true</Enabled>" +
"<Persistence>" +
"<Type>None</Type>" +
"</Persistence>" +
"</InternetService>";
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindInternetServiceToXmlPayload binder = injector
.getInstance(BindInternetServiceToXmlPayload.class);
InternetService.Builder builder = InternetService.builder();
builder.href(URI.create("/cloudapi/ecloud/internetservices/797"));
builder.name("testName");
builder.enabled(true);
builder.persistence(InternetServicePersistenceType.builder().persistenceType(InternetServicePersistenceType.PersistenceType.NONE).build());
binder.bindToRequest(request, builder.build());
assertEquals(request.getPayload().getRawContent(), expected.replaceAll("'","\""));
}
public void testPayloadWithSourceIPXmlContent() throws IOException {
String expected =
"<InternetService name='testName'>" +
"<Enabled>true</Enabled>" +
"<Persistence>" +
"<Type>SourceIp</Type>" +
"</Persistence>" +
"</InternetService>";
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindInternetServiceToXmlPayload binder = injector
.getInstance(BindInternetServiceToXmlPayload.class);
InternetService.Builder builder = InternetService.builder();
builder.href(URI.create("/cloudapi/ecloud/internetservices/797"));
builder.name("testName");
builder.enabled(true);
builder.persistence(InternetServicePersistenceType.builder().persistenceType(InternetServicePersistenceType.PersistenceType.SOURCE_IP).build());
binder.bindToRequest(request, builder.build());
assertEquals(request.getPayload().getRawContent(), expected.replaceAll("'","\""));
}
public void testPayloadWithSourceIPAndTimeoutXmlContent() throws IOException {
String expected =
"<InternetService name='testName'>" +
"<Enabled>true</Enabled>" +
"<Persistence>" +
"<Type>SourceIp</Type>" +
"<Timeout>5</Timeout>" +
"</Persistence>" +
"</InternetService>";
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindInternetServiceToXmlPayload binder = injector
.getInstance(BindInternetServiceToXmlPayload.class);
InternetService.Builder builder = InternetService.builder();
builder.href(URI.create("/cloudapi/ecloud/internetservices/797"));
builder.name("testName");
builder.enabled(true);
builder.persistence(InternetServicePersistenceType.builder().persistenceType(InternetServicePersistenceType.PersistenceType.SOURCE_IP).timeout(5).build());
binder.bindToRequest(request, builder.build());
assertEquals(request.getPayload().getRawContent(), expected.replaceAll("'","\""));
}
public void testPayloadRedirectURLContent() throws IOException {
String expected =
"<InternetService name='testName'>" +
"<Enabled>true</Enabled>" +
"<Persistence>" +
"<Type>None</Type>" +
"</Persistence>" +
"<RedirectUrl>/dev/null</RedirectUrl>" +
"</InternetService>";
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindInternetServiceToXmlPayload binder = injector
.getInstance(BindInternetServiceToXmlPayload.class);
InternetService.Builder builder = InternetService.builder();
builder.href(URI.create("/cloudapi/ecloud/internetservices/797"));
builder.name("testName");
builder.enabled(true);
builder.persistence(InternetServicePersistenceType.builder().persistenceType(InternetServicePersistenceType.PersistenceType.NONE).build());
builder.redirectUrl("/dev/null");
binder.bindToRequest(request, builder.build());
assertEquals(request.getPayload().getRawContent(), expected.replaceAll("'","\""));
}
public void testPayloadTrustedNetworkGroupAndBackupServiceXmlContent() throws IOException {
String expected =
"<InternetService name='testName'>" +
"<Enabled>true</Enabled>" +
"<Persistence>" +
"<Type>None</Type>" +
"</Persistence>" +
"<TrustedNetworkGroup href='/dev/null' name='groupName' type='groupType'/>"+
"<BackupInternetService href='/foo/bar' name='backupName' type='backupType'/>"+
"</InternetService>";
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindInternetServiceToXmlPayload binder = injector
.getInstance(BindInternetServiceToXmlPayload.class);
InternetService.Builder builder = InternetService.builder();
builder.href(URI.create("/cloudapi/ecloud/internetservices/797"));
builder.name("testName");
builder.enabled(true);
builder.persistence(InternetServicePersistenceType.builder().persistenceType(InternetServicePersistenceType.PersistenceType.NONE).build());
builder.trustedNetworkGroup(NamedResource.builder().href(URI.create("/dev/null")).name("groupName").type("groupType").build());
builder.backupInternetService(NamedResource.builder().href(URI.create("/foo/bar")).name("backupName").type("backupType").build());
binder.bindToRequest(request, builder.build());
assertEquals(request.getPayload().getRawContent(), expected.replaceAll("'","\""));
}
}

View File

@ -23,6 +23,7 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseXMLWithJAXB;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import org.testng.annotations.Test;
import java.io.IOException;
@ -54,7 +55,26 @@ public class InternetServiceAsyncClientTest extends BaseTerremarkEnterpriseCloud
checkFilters(httpRequest);
}
public void testEditInternetService() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
Method method = InternetServiceAsyncClient.class.getMethod("editInternetService", InternetService.class);
URI uri = URI.create("/cloudapi/ecloud/internetservices/797");
InternetService service = InternetService.builder().href(uri).build();
HttpRequest httpRequest = processor.createRequest(method, service);
String requestLine = "PUT https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/internetservices/797 HTTP/1.1";
assertRequestLineEquals(httpRequest, requestLine);
assertNonPayloadHeadersEqual(httpRequest,
"Accept: application/vnd.tmrk.cloud.internetService\nx-tmrk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<InternetServiceAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<InternetServiceAsyncClient>>() {

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.tmrk.enterprisecloud.features;
import org.jclouds.tmrk.enterprisecloud.domain.Task;
import org.jclouds.tmrk.enterprisecloud.domain.service.internet.InternetService;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -42,13 +43,39 @@ public class InternetServiceClientLiveTest extends BaseTerremarkEnterpriseCloudC
private InternetServiceClient client;
public void testGetLayouts() throws Exception {
//TODO: THe URI should come from the environment
InternetService internetService = client.getInternetService(URI.create("/cloudapi/ecloud/internetservices/797"));
public void testGetInternetService() throws Exception {
//TODO: The URI should come from the environment
//TODO: Should create a new service edit it then delete it.
//TODO: Need a retryable predicate to wait until the task is done.
URI uri = URI.create("/cloudapi/ecloud/internetservices/797");
InternetService internetService = client.getInternetService(uri);
assertNotNull(internetService);
/*
final String originalName = internetService.getName();
final String newName = originalName+"edited";
boolean enable = !internetService.isEnabled();
// Change the name and enabled flag
testEditInternetService(internetService.getHref(),newName,enable);
internetService = client.getInternetService(uri);
assertEquals(internetService.getName(),newName);
assertEquals(internetService.isEnabled(),enable);
// Change it back again
enable = !internetService.isEnabled();
testEditInternetService(internetService.getHref(),originalName,enable);
assertEquals(internetService.getName(),originalName);
assertEquals(internetService.isEnabled(),enable);
*/
}
public void testGetMissingLayouts() {
public void testGetMissingInternetService() {
assertNull(client.getInternetService(URI.create("/cloudapi/ecloud/internetservices/-1")));
}
private void testEditInternetService(URI uri, String name, boolean enable) {
InternetService service = InternetService.builder().href(uri).name(name).enabled(enable).build();
Task task = client.editInternetService(service);
//TODO: Wait for task to complete.
}
}

View File

@ -104,7 +104,7 @@ public class InternetServiceJAXBParsingTest extends BaseRestClientTest {
assertTrue(internetService.isEnabled());
assertEquals(internetService.getPublicIp(), NamedResource.builder().href(URI.create("/cloudapi/ecloud/publicips/3929")).type("application/vnd.tmrk.cloud.publicIp").name("208.39.65.40").build());
assertEquals(internetService.getPersistence().getPersistenceType(), InternetServicePersistenceType.PersistenceType.NONE);
assertEquals(internetService.getPersistence().getTimeout(), 0); //Default value
assertEquals(internetService.getPersistence().getTimeout(), -1); //Default value
assertEquals(internetService.getMonitor(),NamedResource.builder().href(URI.create("/cloudapi/ecloud/internetservices/797/monitor")).type("application/vnd.tmrk.cloud.defaultMonitor").build());
assertNodeServices(internetService.getNodeServices());