Merge pull request #552 from nacx/configurable-prettyprint

Pretty print in payload is now configurable
This commit is contained in:
Adrian Cole 2012-04-10 08:47:23 -07:00
commit 54184914c5
9 changed files with 436 additions and 308 deletions

View File

@ -34,6 +34,7 @@ import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.xml.XMLParser;
import com.google.common.base.Function;
import com.google.common.eventbus.EventBus;
@ -51,11 +52,11 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut
private final Function<NodeMetadata, SshClient> sshForNode;
@Inject
UtilsImpl(Injector injector, Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, EventBus eventBus,
LoggerFactory loggerFactory, Function<NodeMetadata, SshClient> sshForNode) {
super(injector, json, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, eventBus,
super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, eventBus,
loggerFactory);
this.sshForNode = sshForNode;
}

View File

@ -260,4 +260,11 @@ public interface Constants {
*/
public static final String PROPERTY_TIMEOUTS_PREFIX = "jclouds.timeouts.";
/**
* Boolean property. Default (true).
* <p/>
* Configures the response parsers to pretty print the payload when possible.
*/
public static final String PROPERTY_PRETTY_PRINT_PAYLOADS = "jclouds.payloads.pretty-print";
}

View File

@ -45,6 +45,7 @@ import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import static org.jclouds.Constants.PROPERTY_PRETTY_PRINT_PAYLOADS;
import java.util.Properties;
@ -205,6 +206,14 @@ public class PropertiesBuilder {
return this;
}
/**
* @see org.jclouds.Constants.PROPERTY_PRETTY_PRINT_PAYLOADS
*/
public PropertiesBuilder prettyPrintPayloads(boolean prettyPrintPayloads) {
properties.setProperty(PROPERTY_PRETTY_PRINT_PAYLOADS, Boolean.toString(prettyPrintPayloads));
return this;
}
protected final Properties properties;
public PropertiesBuilder() {
@ -226,6 +235,7 @@ public class PropertiesBuilder {
props.setProperty(PROPERTY_MAX_CONNECTION_REUSE, 75 + "");
props.setProperty(PROPERTY_MAX_SESSION_FAILURES, 2 + "");
props.setProperty(PROPERTY_SESSION_INTERVAL, 60 + "");
props.setProperty(PROPERTY_PRETTY_PRINT_PAYLOADS, "true");
return props;
}

View File

@ -25,6 +25,7 @@ import org.jclouds.date.DateService;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.internal.UtilsImpl;
import org.jclouds.xml.XMLParser;
import com.google.common.annotations.Beta;
import com.google.common.eventbus.EventBus;
@ -111,4 +112,11 @@ public interface Utils {
@Beta
Injector injector();
XMLParser getXml();
/**
* #see #getXml
*/
XMLParser xml();
}

View File

@ -31,6 +31,7 @@ import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient;
import org.jclouds.rest.Utils;
import org.jclouds.xml.XMLParser;
import com.google.common.annotations.Beta;
import com.google.common.eventbus.EventBus;
@ -53,9 +54,10 @@ public class UtilsImpl implements Utils {
private final EventBus eventBus;
private final LoggerFactory loggerFactory;
private Injector injector;
private XMLParser xml;
@Inject
protected UtilsImpl(Injector injector, Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
protected UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, EventBus eventBus,
LoggerFactory loggerFactory) {
@ -69,6 +71,7 @@ public class UtilsImpl implements Utils {
this.ioExecutor = ioThreads;
this.eventBus = eventBus;
this.loggerFactory = loggerFactory;
this.xml = xml;
}
@Override
@ -173,4 +176,14 @@ public class UtilsImpl implements Utils {
return getInjector();
}
@Override
public XMLParser getXml() {
return xml;
}
@Override
public XMLParser xml() {
return xml;
}
}

View File

@ -22,15 +22,19 @@ import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.jclouds.Constants;
import org.jclouds.http.functions.ParseXMLWithJAXB;
import org.jclouds.xml.XMLParser;
import com.google.inject.name.Named;
/**
* Parses XML documents using JAXB.
*
@ -39,6 +43,16 @@ import org.jclouds.xml.XMLParser;
*/
@Singleton
public class JAXBParser implements XMLParser {
/** Boolean indicating if the output must be pretty printed. */
private Boolean prettyPrint;
@Inject
public JAXBParser(@Named(Constants.PROPERTY_PRETTY_PRINT_PAYLOADS) String prettyPrint) {
super();
this.prettyPrint = Boolean.valueOf(prettyPrint);
}
@Override
public String toXML(final Object src) throws IOException {
return toXML(src, src.getClass());
@ -49,7 +63,7 @@ public class JAXBParser implements XMLParser {
try {
JAXBContext context = JAXBContext.newInstance(type);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, prettyPrint);
StringWriter writer = new StringWriter();
marshaller.marshal(src, writer);
return writer.toString();
@ -58,6 +72,7 @@ public class JAXBParser implements XMLParser {
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T fromXML(final String xml, final Class<T> type) throws IOException {
try {

View File

@ -40,7 +40,7 @@ import com.google.common.collect.Multimap;
*/
@Test(groups = "unit", testName = "BindToXMLPayloadTest")
public class BindToXMLPayloadTest {
XMLParser xml = new JAXBParser();
XMLParser xml = new JAXBParser("true");
@Test
public void testBindJAXBObject() throws SecurityException, NoSuchMethodException {

View File

@ -74,10 +74,13 @@ import com.google.common.collect.Iterables;
*
* @author grkvlt@apache.org
*/
public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClientLiveTest {
public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClientLiveTest
{
public static final String VAPP = "vApp";
public static final String VAPP_TEMPLATE = "vAppTemplate";
public static final String VDC = "vdc";
/*
@ -85,10 +88,15 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*/
protected CatalogClient catalogClient;
protected QueryClient queryClient;
protected VAppClient vAppClient;
protected VAppTemplateClient vAppTemplateClient;
protected VdcClient vdcClient;
protected MetadataClient.Writeable metadataClient;
/*
@ -96,9 +104,13 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*/
protected Vdc vdc;
protected Vm vm;
protected URI vAppURI;
protected VApp vApp;
protected VAppTemplate vAppTemplate;
/**
@ -108,7 +120,8 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*/
@Override
@BeforeClass(alwaysRun = true, description = "Retrieves the required clients from the REST API context")
protected void setupRequiredClients() {
protected void setupRequiredClients()
{
assertNotNull(context.getApi());
catalogClient = context.getApi().getCatalogClient();
@ -121,12 +134,11 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
}
/**
* Sets up the environment.
*
* Retrieves the test {@link Vdc} and {@link VAppTemplate} from their configured {@link URI}s.
* Instantiates a new test VApp.
* Sets up the environment. Retrieves the test {@link Vdc} and {@link VAppTemplate} from their
* configured {@link URI}s. Instantiates a new test VApp.
*/
protected void setupEnvironment() {
protected void setupEnvironment()
{
// Get the configured Vdc for the tests
vdc = vdcClient.getVdc(vdcURI);
assertNotNull(vdc, String.format(ENTITY_NON_NULL, VDC));
@ -142,7 +154,8 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
// Wait for the task to complete
Task instantiateTask = Iterables.getOnlyElement(vAppInstantiated.getTasks());
assertTrue(retryTaskSuccessLong.apply(instantiateTask), String.format(TASK_COMPLETE_TIMELY, "instantiateTask"));
assertTrue(retryTaskSuccessLong.apply(instantiateTask),
String.format(TASK_COMPLETE_TIMELY, "instantiateTask"));
// Get the instantiated VApp
vApp = vAppClient.getVApp(vAppURI);
@ -153,95 +166,122 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
assertFalse(vms.isEmpty(), "The VApp must have a Vm");
}
protected void getGuestCustomizationSection(Function<URI, GuestCustomizationSection> getGuestCustomizationSection) {
protected void getGuestCustomizationSection(
final Function<URI, GuestCustomizationSection> getGuestCustomizationSection)
{
// Get URI for child VM
URI vmURI = Iterables.getOnlyElement(vApp.getChildren().getVms()).getHref();
// The method under test
try {
try
{
GuestCustomizationSection section = getGuestCustomizationSection.apply(vmURI);
// Check the retrieved object is well formed
checkGuestCustomizationSection(section);
} catch (Exception e) {
}
catch (Exception e)
{
Throwables.propagate(e);
}
}
protected void getNetworkConnectionSection(Function<URI, NetworkConnectionSection> getNetworkConnectionSection) {
protected void getNetworkConnectionSection(
final Function<URI, NetworkConnectionSection> getNetworkConnectionSection)
{
// Get URI for child VM
URI vmURI = Iterables.getOnlyElement(vApp.getChildren().getVms()).getHref();
// The method under test
try {
try
{
NetworkConnectionSection section = getNetworkConnectionSection.apply(vmURI);
// Check the retrieved object is well formed
checkNetworkConnectionSection(section);
} catch (Exception e) {
}
catch (Exception e)
{
Throwables.propagate(e);
}
}
@AfterClass(alwaysRun = true, description = "Cleans up the environment by deleting created VApps")
protected void cleanUp() {
protected void cleanUp()
{
vdc = vdcClient.getVdc(vdcURI); // Refresh
// Find references in the Vdc with the VApp type and in the list of instantiated VApp names
Iterable<Reference> vApps = Iterables.filter(
vdc.getResourceEntities(),
Predicates.and(
Iterable<Reference> vApps =
Iterables.filter(vdc.getResourceEntities(), Predicates.and(
ReferencePredicates.<Reference> typeEquals(VCloudDirectorMediaType.VAPP),
ReferencePredicates.<Reference>nameIn(vAppNames)
)
);
ReferencePredicates.<Reference> nameIn(vAppNames)));
// If we found any references, delete the VApp they point to
if (!Iterables.isEmpty(vApps)) {
for (Reference ref : vApps) {
if (!Iterables.isEmpty(vApps))
{
for (Reference ref : vApps)
{
cleanUpVApp(ref.getHref()); // NOTE may fail, but should continue deleting
}
} else {
logger.warn("No VApps in list found in Vdc %s (%s)", vdc.getName(), Iterables.toString(vAppNames));
}
else
{
logger.warn("No VApps in list found in Vdc %s (%s)", vdc.getName(),
Iterables.toString(vAppNames));
}
}
protected static CimBoolean cimBoolean(boolean val) {
protected static CimBoolean cimBoolean(final boolean val)
{
CimBoolean result = new CimBoolean();
result.setValue(val);
return result;
}
protected static CimUnsignedInt cimUnsignedInt(long val) {
protected static CimUnsignedInt cimUnsignedInt(final long val)
{
CimUnsignedInt result = new CimUnsignedInt();
result.setValue(val);
return result;
}
protected static CimUnsignedLong cimUnsignedLong(BigInteger val) {
protected static CimUnsignedLong cimUnsignedLong(final BigInteger val)
{
CimUnsignedLong result = new CimUnsignedLong();
result.setValue(val);
return result;
}
protected static CimString cimString(String value) {
protected static CimString cimString(final String value)
{
return new CimString(value);
}
protected void checkHasMatchingItem(final String context, final RasdItemsList items, final String instanceId, final String elementName) {
Optional<ResourceAllocationSettingData> found = Iterables.tryFind(items.getItems(), new Predicate<ResourceAllocationSettingData>() {
protected void checkHasMatchingItem(final String context, final RasdItemsList items,
final String instanceId, final String elementName)
{
Optional<ResourceAllocationSettingData> found =
Iterables.tryFind(items.getItems(), new Predicate<ResourceAllocationSettingData>()
{
@Override
public boolean apply(ResourceAllocationSettingData item) {
public boolean apply(final ResourceAllocationSettingData item)
{
String itemInstanceId = item.getInstanceID();
if (itemInstanceId.equals(instanceId)) {
Assert.assertEquals(item.getElementName(), elementName,
String.format(OBJ_FIELD_EQ, VAPP, context + "/" + instanceId + "/elementName", elementName, item.getElementName()));
if (itemInstanceId.equals(instanceId))
{
Assert.assertEquals(
item.getElementName(),
elementName,
String.format(OBJ_FIELD_EQ, VAPP, context + "/" + instanceId
+ "/elementName", elementName, item.getElementName()));
return true;
}
return false;
}
});
assertTrue(found.isPresent(), "no " + context + " item found with id " + instanceId + "; only found " + items);
assertTrue(found.isPresent(), "no " + context + " item found with id " + instanceId
+ "; only found " + items);
}
/**
@ -249,18 +289,21 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*
* @see #powerOn(URI)
*/
protected VApp powerOn(VApp testVApp) {
protected VApp powerOn(final VApp testVApp)
{
return powerOn(testVApp.getHref());
}
/**
* Power on a VApp.
*/
protected VApp powerOn(URI testVAppURI) {
protected VApp powerOn(final URI testVAppURI)
{
VApp testVApp = vAppClient.getVApp(testVAppURI);
Vm vm = Iterables.getOnlyElement(testVApp.getChildren().getVms());
Status status = Status.fromValue(vm.getStatus());
if (status != Status.POWERED_ON) {
if (status != Status.POWERED_ON)
{
Task powerOn = vAppClient.powerOn(vm.getHref());
assertTaskSucceedsLong(powerOn);
}
@ -273,18 +316,21 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*
* @see #powerOff(URI)
*/
protected VApp powerOff(VApp testVApp) {
protected VApp powerOff(final VApp testVApp)
{
return powerOff(testVApp.getHref());
}
/**
* Power off a {@link VApp}s {@link Vm}s.
*/
protected VApp powerOff(URI testVAppURI) {
protected VApp powerOff(final URI testVAppURI)
{
VApp testVApp = vAppClient.getVApp(testVAppURI);
Vm vm = Iterables.getOnlyElement(testVApp.getChildren().getVms());
Status status = Status.fromValue(vm.getStatus());
if (status != Status.POWERED_OFF) {
if (status != Status.POWERED_OFF)
{
Task powerOff = vAppClient.powerOff(vm.getHref());
assertTaskSucceedsLong(powerOff);
}
@ -297,18 +343,21 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
*
* @see #suspend(URI)
*/
protected VApp suspend(VApp testVApp) {
protected VApp suspend(final VApp testVApp)
{
return powerOff(testVApp.getHref());
}
/**
* Suspend a {@link VApp}s {@link Vm}s.
*/
protected VApp suspend(URI testVAppURI) {
protected VApp suspend(final URI testVAppURI)
{
VApp testVApp = vAppClient.getVApp(testVAppURI);
Vm vm = Iterables.getOnlyElement(testVApp.getChildren().getVms());
Status status = Status.fromValue(vm.getStatus());
if (status != Status.SUSPENDED) {
if (status != Status.SUSPENDED)
{
Task suspend = vAppClient.suspend(vm.getHref());
assertTaskSucceedsLong(suspend);
}
@ -319,25 +368,34 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
/**
* Check the {@link VApp}s {@link Vm}s current status.
*/
protected void assertVAppStatus(URI testVAppURI, Status status) {
protected void assertVAppStatus(final URI testVAppURI, final Status status)
{
VApp testVApp = vAppClient.getVApp(testVAppURI);
Vm vm = Iterables.getOnlyElement(testVApp.getChildren().getVms());
assertEquals(vm.getStatus(), status.getValue(),String.format(OBJ_FIELD_EQ, VAPP, "status", status.toString(), Status.fromValue(vm.getStatus()).toString()));
assertEquals(
vm.getStatus(),
status.getValue(),
String.format(OBJ_FIELD_EQ, VAPP, "status", status.toString(),
Status.fromValue(vm.getStatus()).toString()));
}
/**
* Marshals a JAXB annotated object into XML.
*
* The XML is output using {@link org.jclouds.logging.Logger#debug(String)}
* Marshals a JAXB annotated object into XML. The XML is output using
* {@link org.jclouds.logging.Logger#debug(String)}
*/
protected void debug(Object object) {
JAXBParser parser = new JAXBParser();
try {
protected void debug(final Object object)
{
JAXBParser parser = new JAXBParser("true");
try
{
String xml = parser.toXML(object);
logger.debug(Strings.padStart(Strings.padEnd(" " + object.getClass().toString() + " ", 70, '-'), 80, '-'));
logger.debug(Strings.padStart(
Strings.padEnd(" " + object.getClass().toString() + " ", 70, '-'), 80, '-'));
logger.debug(xml);
logger.debug(Strings.repeat("-", 80));
} catch (IOException ioe) {
}
catch (IOException ioe)
{
Throwables.propagate(ioe);
}
}

View File

@ -46,73 +46,89 @@ import com.google.common.collect.Iterables;
* @author danikov
*/
@Test(groups = {"live", "user", "nonClient"}, singleThreaded = true, testName = "NonClientOperationsLiveTest")
public class NonClientOperationsLiveTest extends BaseVCloudDirectorClientLiveTest {
public class NonClientOperationsLiveTest extends BaseVCloudDirectorClientLiveTest
{
private JAXBParser parser = new JAXBParser("true");
private JAXBParser parser = new JAXBParser();
private SessionWithToken sessionWithToken;
@Override
protected void setupRequiredClients() throws Exception {
protected void setupRequiredClients() throws Exception
{
setupCredentials();
}
@Test(testName = "POST /login")
public void testPostLogin() throws IOException {
public void testPostLogin() throws IOException
{
testLoginWithMethod("POST");
}
@Test(testName = "GET /login")
public void testGetLogin() throws IOException {
public void testGetLogin() throws IOException
{
testLoginWithMethod("GET");
}
private void testLoginWithMethod(String method) throws IOException {
private void testLoginWithMethod(final String method) throws IOException
{
String user = identity.substring(0, identity.lastIndexOf('@'));
String org = identity.substring(identity.lastIndexOf('@') + 1);
String password = credential;
String authHeader = "Basic " + CryptoStreams.base64(String.format("%s@%s:%s",
checkNotNull(user),
checkNotNull(org),
checkNotNull(password)).getBytes("UTF-8"));
String authHeader =
"Basic "
+ CryptoStreams.base64(String.format("%s@%s:%s", checkNotNull(user),
checkNotNull(org), checkNotNull(password)).getBytes("UTF-8"));
HttpResponse response = context.getUtils().getHttpClient().invoke(HttpRequest.builder()
HttpResponse response =
context
.getUtils()
.getHttpClient()
.invoke(
HttpRequest
.builder()
.method(method)
.endpoint(URI.create(endpoint + "/login"))
.headers(ImmutableMultimap.of(
"Authorization", authHeader,
"Accept", "*/*"))
.headers(ImmutableMultimap.of("Authorization", authHeader, "Accept", "*/*"))
.build());
sessionWithToken = SessionWithToken.builder()
.session(session)
.token(response.getFirstHeaderOrNull("x-vcloud-authorization"))
.build();
sessionWithToken =
SessionWithToken.builder().session(session)
.token(response.getFirstHeaderOrNull("x-vcloud-authorization")).build();
assertEquals(sessionWithToken.getSession().getUser(), user);
assertEquals(sessionWithToken.getSession().getOrg(), org);
assertTrue(sessionWithToken.getSession().getLinks().size() > 0);
assertNotNull(sessionWithToken.getToken());
OrgList orgList = parser.fromXML(
Strings2.toStringAndClose(response.getPayload().getInput()), OrgList.class);
OrgList orgList =
parser.fromXML(Strings2.toStringAndClose(response.getPayload().getInput()),
OrgList.class);
assertTrue(orgList.getOrgs().size() > 0, "must have orgs");
context.getApi().getOrgClient().getOrg(Iterables.getLast(orgList.getOrgs()).getHref());
}
@Test(testName = "GET /schema/{schemaFileName}",
dependsOnMethods = {"testPostLogin", "testGetLogin"} )
public void testGetSchema() throws IOException {
@Test(testName = "GET /schema/{schemaFileName}", dependsOnMethods = {"testPostLogin",
"testGetLogin"})
public void testGetSchema() throws IOException
{
String schemafileName = "master.xsd";
HttpResponse response = context.getUtils().getHttpClient().invoke(HttpRequest.builder()
HttpResponse response =
context
.getUtils()
.getHttpClient()
.invoke(
HttpRequest
.builder()
.method("GET")
.endpoint(URI.create(endpoint + "/v1.5/schema/" + schemafileName))
.headers(ImmutableMultimap.of(
"x-vcloud-authorization", sessionWithToken.getToken(),
"Accept", "*/*"))
.build());
.headers(
ImmutableMultimap.of("x-vcloud-authorization",
sessionWithToken.getToken(), "Accept", "*/*")).build());
String schema = Strings2.toStringAndClose(response.getPayload().getInput());