Issue 167: patched in jclouds http so we can see log statements

This commit is contained in:
Adrian Cole 2011-01-13 10:25:01 -08:00
parent 5decc437f1
commit f334bca7c8
3 changed files with 502 additions and 48 deletions

View File

@ -0,0 +1,384 @@
/*================================================================================
Copyright (c) 2009 VMware, Inc. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of VMware, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
================================================================================*/
package com.vmware.vim25.ws;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.vmware.vim25.ManagedObjectReference;
import java.rmi.RemoteException;
/**
*
* Patched to include logging
*
* The Web Service Engine
* @author Steve Jin (sjin@vmware.com)
*/
public class WSClient
{
private final static String SOAP_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body>";
private final static String SOAP_END = "</soapenv:Body></soapenv:Envelope>";
private final static String SOAP_ACTION_HEADER = "SOAPAction";
private final static String SOAP_ACTION_V40 = "urn:vim25/4.0";
private final static String SOAP_ACTION_V41 = "urn:vim25/4.1";
private URL baseUrl = null;
private String cookie = null;
private String vimNameSpace = null;
private String soapAction = SOAP_ACTION_V40;
private int connectTimeout = 0;
private int readTimeout = 0;
public WSClient(String serverUrl) throws MalformedURLException
{
this(serverUrl, true);
}
public WSClient(String serverUrl, boolean ignoreCert) throws MalformedURLException
{
if(serverUrl.endsWith("/"))
{
serverUrl = serverUrl.substring(0, serverUrl.length()-1);
}
this.baseUrl = new URL(serverUrl);
if(ignoreCert)
{
try
{
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier
(
new HostnameVerifier()
{
public boolean verify(String urlHostName, SSLSession session)
{
return true;
}
}
);
} catch (Exception e) {}
}
}
public Object invoke(ManagedObjectReference mor, String methodName, Argument[] paras, String returnType) throws IOException
{
Argument[] fullParas = new Argument[paras.length + 1];
fullParas[0] = new Argument("_this", "ManagedObjectReference", mor);
System.arraycopy(paras, 0, fullParas, 1, paras.length);
return invoke(methodName, fullParas, returnType);
}
public Object invoke(String methodName, Argument[] paras, String returnType) throws RemoteException
{
Element root = invoke(methodName, paras);
Element body = (Element) root.elements().get(0);
Element resp = (Element) body.elements().get(0);
if(resp.getName().indexOf("Fault")!=-1)
{
SoapFaultException sfe = null;
try
{
sfe = XmlGen.parseSoapFault(resp);
}
catch (Exception e)
{
throw new RemoteException("Exception in WSClient.invoke:", e);
}
if(sfe!=null && sfe.detail!=null)
{
throw (RemoteException) sfe.detail;
}
else
{
throw sfe;
}
}
else
{
if(returnType!=null)
{
try
{
return XmlGen.fromXML(returnType, resp);
}
catch (Exception e)
{
throw new RemoteException("Exception in WSClient.invoke:", e);
}
}
else
{
return null;
}
}
}
public Element invoke(String methodName, Argument[] paras) throws RemoteException
{
String soapMsg = createSoapMessage(methodName, paras);
Element root = null;
InputStream is = null;
try
{
is = post(soapMsg);
SAXReader reader = new SAXReader();
Document doc = reader.read(is);
root = doc.getRootElement();
} catch (Exception e)
{
throw new RemoteException("VI SDK invoke exception:" + e);
}
finally
{
if(is!=null)
try { is.close(); } catch(IOException ioe) {}
}
return root;
}
public StringBuffer invokeAsString(String methodName, Argument[] paras) throws RemoteException
{
String soapMsg = createSoapMessage(methodName, paras);
try
{
InputStream is = post(soapMsg);
return readStream(is);
} catch (Exception e)
{
throw new RemoteException("VI SDK invoke exception:" + e);
}
}
private String createSoapMessage(String methodName, Argument[] paras)
{
StringBuffer sb = new StringBuffer();
sb.append(SOAP_HEADER);
sb.append("<" + methodName + vimNameSpace);
for(int i=0; i<paras.length; i++)
{
String key = paras[i].getName();
String type = paras[i].getType();
Object obj = paras[i].getValue();
sb.append(XmlGen.toXML(key, type, obj)); //, null));
}
sb.append("</" + methodName + ">");
sb.append(SOAP_END);
return sb.toString();
}
public InputStream post(String soapMsg) throws IOException
{
HttpURLConnection postCon = (HttpURLConnection) baseUrl.openConnection();
if(connectTimeout > 0)
postCon.setConnectTimeout(connectTimeout);
if(readTimeout > 0)
postCon.setReadTimeout(readTimeout);
try {
postCon.setRequestMethod("POST");
} catch (ProtocolException e)
{
e.printStackTrace();
}
postCon.setDoOutput(true);
postCon.setDoInput(true);
postCon.setRequestProperty(SOAP_ACTION_HEADER, soapAction);
if(cookie!=null)
{
postCon.setRequestProperty("Cookie", cookie);
}
OutputStream os = postCon.getOutputStream();
OutputStreamWriter out = new OutputStreamWriter(os);
out.write(soapMsg);
out.close();
InputStream is;
try
{
is = postCon.getInputStream();
}
catch(IOException ioe)
{
is = postCon.getErrorStream();
}
if(cookie==null)
{
cookie = postCon.getHeaderField("Set-Cookie");
}
return is;
}
public URL getBaseUrl()
{
return this.baseUrl;
}
public void setBaseUrl(URL baseUrl)
{
this.baseUrl = baseUrl;
}
public String getCookie()
{
return cookie;
}
public void setCookie(String cookie)
{
this.cookie = cookie;
}
public String getVimNameSpace()
{
return vimNameSpace;
}
public void setVimNameSpace(String vimNameSpace)
{
this.vimNameSpace = vimNameSpace;
}
public void setConnectTimeout(int timeoutMilliSec)
{
this.connectTimeout = timeoutMilliSec;
}
public int getConnectTimeout()
{
return this.connectTimeout;
}
public void setReadTimeout(int timeoutMilliSec)
{
this.readTimeout = timeoutMilliSec;
}
public int getReadTimeout()
{
return this.readTimeout;
}
/*===============================================
* API versions *
"2.0.0" VI 3.0
"2.5.0" VI 3.5 (and u1)
"2.5u2" VI 3.5u2 (and u3, u4)
"4.0" vSphere 4.0 (and u1)
"4.1" vSphere 4.1
===============================================*/
public void setSoapActionOnApiVersion(String apiVersion)
{
//4.0 is set by default already, so skip it here
if("4.1".equals(apiVersion))
{
soapAction = SOAP_ACTION_V41;
}
}
private StringBuffer readStream(InputStream is) throws IOException
{
StringBuffer sb = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String lineStr;
while ((lineStr = in.readLine()) != null)
{
sb.append(lineStr);
}
in.close();
return sb;
}
private static void trustAllHttpsCertificates()
throws NoSuchAlgorithmException, KeyManagementException
{
TrustManager[] trustAllCerts = new TrustManager[1];
trustAllCerts[0] = new TrustAllManager();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
}
private static class TrustAllManager implements X509TrustManager
{
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkServerTrusted(X509Certificate[] certs,
String authType)
throws CertificateException
{
}
public void checkClientTrusted(X509Certificate[] certs,
String authType)
throws CertificateException
{
}
}
}

View File

@ -26,12 +26,17 @@ import static com.google.common.collect.Iterables.transform;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.HttpHeaders;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.commons.io.filefilter.WildcardFileFilter;
@ -42,9 +47,13 @@ import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.io.Payloads;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.rest.HttpClient;
import org.jclouds.vi.Image; import org.jclouds.vi.Image;
import org.jclouds.vi.compute.functions.DatacenterToLocation; import org.jclouds.vi.compute.functions.DatacenterToLocation;
import org.jclouds.vi.compute.functions.ViImageToImage; import org.jclouds.vi.compute.functions.ViImageToImage;
@ -56,13 +65,19 @@ import org.xml.sax.SAXException;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.vmware.vim25.VimPortType;
import com.vmware.vim25.mo.Datacenter; import com.vmware.vim25.mo.Datacenter;
import com.vmware.vim25.mo.ServerConnection;
import com.vmware.vim25.mo.ServiceInstance; import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine; import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.ws.WSClient;
/** /**
* *
@ -95,10 +110,62 @@ public class ViComputeServiceContextModule
@Provides @Provides
@Singleton @Singleton
protected ServiceInstance createConnection(@Provider URI endpoint, protected ServiceInstance createConnection(HttpClient client, @Provider URI endpoint,
@Named(Constants.PROPERTY_IDENTITY) String identity, @Named(Constants.PROPERTY_CREDENTIAL) String credential) @Named(Constants.PROPERTY_IDENTITY) String identity, @Named(Constants.PROPERTY_CREDENTIAL) String credential)
throws RemoteException, MalformedURLException { throws RemoteException, MalformedURLException, SecurityException, NoSuchFieldException,
return new ServiceInstance(endpoint.toURL(), identity, credential, true); IllegalArgumentException, IllegalAccessException, URISyntaxException {
ServiceInstance foo = new ServiceInstance(endpoint.toURL(), identity, credential, true);
Field serverConnectionField = ServiceInstance.class.getDeclaredField("serverConnection");
serverConnectionField.setAccessible(true);
ServerConnection connection = (ServerConnection) serverConnectionField.get(foo);
Field vimServiceField = ServerConnection.class.getDeclaredField("vimService");
vimServiceField.setAccessible(true);
VimPortType vim = (VimPortType) vimServiceField.get(connection);
Field wscField = VimPortType.class.getDeclaredField("wsc");
wscField.setAccessible(true);
WSClient oldClient = (WSClient) wscField.get(vim);
wscField.set(vim, new JcloudsWSClient(client, oldClient.getBaseUrl().toURI(), oldClient.getCookie(), oldClient
.getVimNameSpace()));
return foo;
}
static class JcloudsWSClient extends WSClient {
private final HttpClient client;
public JcloudsWSClient(HttpClient client, URI baseUrl, String cookie, String vimNameSpace)
throws MalformedURLException {
super(baseUrl.toASCIIString(), false);
this.setCookie(cookie);
this.setVimNameSpace(vimNameSpace);
this.client = client;
}
@Override
public InputStream post(String soapMsg) throws IOException {
Builder<String, String> headers = ImmutableMultimap.<String, String> builder();
headers.put("SOAPAction", "urn:vim25/4.0");
if (getCookie() != null)
headers.put(HttpHeaders.COOKIE, getCookie());
HttpRequest request;
try {
request = HttpRequest.builder().endpoint(getBaseUrl().toURI()).method("POST").headers(headers.build())
.payload(Payloads.newStringPayload(soapMsg)).build();
} catch (URISyntaxException e) {
Throwables.propagate(e);
return null;// unreachable as the above line will throw the exception.
}
HttpResponse response = client.invoke(request);
if (getCookie() != null && response.getFirstHeaderOrNull(HttpHeaders.SET_COOKIE) != null) {
setCookie(response.getFirstHeaderOrNull(HttpHeaders.SET_COOKIE));
}
return response.getPayload().getInput();
}
} }
@Override @Override
@ -119,22 +186,22 @@ public class ViComputeServiceContextModule
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private String searchForHardwareIdInDomainDir(String domainDir, final ParseSax.Factory factory, private String searchForHardwareIdInDomainDir(String domainDir, final ParseSax.Factory factory,
final javax.inject.Provider<UUIDHandler> provider) { final javax.inject.Provider<UUIDHandler> provider) {
//TODO: remove commons-io dependency
return Iterables.<String>getLast(filter(transform(FileUtils.listFiles(new File(domainDir), new WildcardFileFilter("*.xml"), null),
new Function<File, String>() {
@Override // TODO: remove commons-io dependency
public String apply(File input) { return Iterables.<String> getLast(filter(transform(FileUtils.listFiles(new File(domainDir),
try { new WildcardFileFilter("*.xml"), null), new Function<File, String>() {
return factory.create(provider.get()).parse(new FileInputStream(input));
} catch (FileNotFoundException e) {
// log error.
return null;
}
}
}), notNull())); @Override
public String apply(File input) {
try {
return factory.create(provider.get()).parse(new FileInputStream(input));
} catch (FileNotFoundException e) {
// log error.
return null;
}
}
}), notNull()));
} }
public static class UUIDHandler extends ParseSax.HandlerWithResult<String> { public static class UUIDHandler extends ParseSax.HandlerWithResult<String> {

View File

@ -21,17 +21,21 @@ package org.jclouds.vi.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -56,50 +60,49 @@ public class ViExperimentLiveTest {
public void testAndExperiment() { public void testAndExperiment() {
ComputeServiceContext context = null; ComputeServiceContext context = null;
try { try {
context = new ComputeServiceContextFactory().createContext(new ViComputeServiceContextSpec( context = new ComputeServiceContextFactory().createContext(new ViComputeServiceContextSpec(endpoint, identity,
endpoint, identity, credential)); credential), ImmutableSet.<Module>of(new Log4JLoggingModule()), new Properties());
Set<? extends Location> locations = context.getComputeService().listAssignableLocations(); Set<? extends Location> locations = context.getComputeService().listAssignableLocations();
for (Location location : locations) { for (Location location : locations) {
System.out.println("location id: " + location.getId() + " - desc: " + location.getDescription()); System.out.println("location id: " + location.getId() + " - desc: " + location.getDescription());
} }
// Set<? extends ComputeMetadata> nodes = context.getComputeService().listNodes(); // Set<? extends ComputeMetadata> nodes = context.getComputeService().listNodes();
// //
Set<? extends Hardware> hardwares = context.getComputeService().listHardwareProfiles(); Set<? extends Hardware> hardwares = context.getComputeService().listHardwareProfiles();
for (Hardware hardware : hardwares) { for (Hardware hardware : hardwares) {
System.out.println("hardware id: " + hardware.getId() + " - name: " + hardware.getName()); System.out.println("hardware id: " + hardware.getId() + " - name: " + hardware.getName());
} }
// //
Set<? extends Image> images = context.getComputeService().listImages(); Set<? extends Image> images = context.getComputeService().listImages();
for (Image image : images) { for (Image image : images) {
System.out.println("id: " + image.getId() + " - name:" + image.getName()); System.out.println("id: " + image.getId() + " - name:" + image.getName());
} }
// //
// NodeMetadata node = context.getComputeService().getNodeMetadata("MyWinServer"); // NodeMetadata node = context.getComputeService().getNodeMetadata("MyWinServer");
// System.out.println(node); // System.out.println(node);
/* /*
* We will probably make a default template out of properties at some point You can control * We will probably make a default template out of properties at some point You can control
* the default template via overriding a method in standalonecomputeservicexontextmodule * the default template via overriding a method in standalonecomputeservicexontextmodule
*/ */
/* /*
Template defaultTemplate = context.getComputeService().templateBuilder() * Template defaultTemplate = context.getComputeService().templateBuilder()
.hardwareId("vm-1221").imageId("winNetEnterprise64Guest") //.locationId("") * .hardwareId("vm-1221").imageId("winNetEnterprise64Guest") //.locationId("") .build();
.build(); *
* Set<? extends NodeMetadata> nodeMetadataSet =
Set<? extends NodeMetadata> nodeMetadataSet = context.getComputeService().runNodesWithTag("MyWinServer", 1); * context.getComputeService().runNodesWithTag("MyWinServer", 1); for (NodeMetadata
for (NodeMetadata nodeMetadata : nodeMetadataSet) { * nodeMetadata : nodeMetadataSet) {
*
// context.getComputeService().suspendNode(nodeMetadata.getId()); * // context.getComputeService().suspendNode(nodeMetadata.getId()); //
// context.getComputeService().resumeNode(nodeMetadata.getId()); * context.getComputeService().resumeNode(nodeMetadata.getId());
*
//context.getComputeService().destroyNode(nodeMetadata.getId()); * //context.getComputeService().destroyNode(nodeMetadata.getId()); }
} */
*/
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (context != null) if (context != null)
context.close(); context.close();