Java Requires Chilkat v11.0.0+
Java
Xero API through an SSH Tunnel
This example demonstrates connecting through an SSH Tunnel w/ 2-legged OAuth for a Xero private application.Chilkat Java Downloads
import com.chilkatsoft.*;
public class ChilkatExample {
static {
try {
System.loadLibrary("chilkat");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
boolean success = false;
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
CkSocket tunnel = new CkSocket();
String sshHostname = "sftp.example.com";
int sshPort = 22;
// Connect to an SSH server and establish the SSH tunnel:
success = tunnel.SshOpenTunnel(sshHostname,sshPort);
if (success == false) {
System.out.println(tunnel.lastErrorText());
return;
}
// Authenticate with the SSH server via a login/password
// or with a public key.
// This example demonstrates SSH password authentication.
success = tunnel.SshAuthenticatePw("mySshLogin","mySshPassword");
if (success == false) {
System.out.println(tunnel.lastErrorText());
return;
}
// OK, the SSH tunnel is setup. Now open a channel within the tunnel.
// (Any number of channels may be created from the same SSH tunnel.
// Multiple channels may coexist at the same time.)
// This sample code would typically be placed in a subroutine or function
// where the rest object is passed by reference.
// It does the OAuth1 setup and makes the initial connection.
CkRest rest = new CkRest();
boolean bTls = true;
int port = 443;
int maxWaitMs = 7000;
// This returns a socket object that is a single channel within the SSH tunnel.
CkSocket channel = new CkSocket();
success = tunnel.SshNewChannel("api.xero.com",port,bTls,maxWaitMs,channel);
if (success == false) {
System.out.println(tunnel.lastErrorText());
return;
}
// Use the connection. (This connection is a TLS running on an SSH channel through an SSH tunnel.
// In other words, TLS is wrapped within the SSH tunnel.)
success = rest.UseConnection(channel,true);
if (success == false) {
System.out.println(rest.lastErrorText());
return;
}
// OK, we're connected.
// -----------------------------------------------------------------
// Now setup the OAuth1 authenticator..
String consumerKey = "XERO_PRIVATE_APP_KEY";
String consumerSecret = "XERO_PRIVATE_APP_SECRET";
// Let's get our private key from our PFX (password protected), or the PEM (unprotected).
// You can decide which to use. Either is OK, although I would recommend keeping your
// private keys in a PFX and not in an unprotected PEM.
CkPfx pfx = new CkPfx();
success = pfx.LoadPfxFile("qa_data/certs/xero_private_app/public_privatekey.pfx","PFX_PASSWORD");
if (success == false) {
System.out.println(pfx.lastErrorText());
return;
}
CkPrivateKey privKeyFromPfx = new CkPrivateKey();
success = pfx.PrivateKeyAt(0,privKeyFromPfx);
if (success == false) {
System.out.println(pfx.lastErrorText());
return;
}
// Or we can load from a PEM..
CkPrivateKey privKeyFromPem = new CkPrivateKey();
success = privKeyFromPem.LoadPemFile("qa_data/certs/xero_private_app/privatekey.pem");
if (success == false) {
System.out.println(privKeyFromPem.lastErrorText());
return;
}
// Note: There are many other means for loading a private key, including
// from other formats and directly from memory (i.e. not file-based).
CkOAuth1 oauth1 = new CkOAuth1();
oauth1.put_ConsumerKey(consumerKey);
oauth1.put_ConsumerSecret(consumerSecret);
oauth1.put_Token(consumerKey);
oauth1.put_TokenSecret(consumerSecret);
oauth1.put_SignatureMethod("RSA-SHA1");
oauth1.SetRsaKey(privKeyFromPfx);
// Install the OAuth1 authenticator.
rest.SetAuthOAuth1(oauth1,false);
System.out.println("OK, the Xero OAuth1 is initialized and the REST object is ready to make REST API calls..");
// -----------------------------------------------------------------
// Make a call to verify that OAuth1 through an HTTP proxy works..
// Get the full list of contacts.
CkStringBuilder sbXml = new CkStringBuilder();
success = rest.FullRequestNoBodySb("GET","/api.xro/2.0/Contacts",sbXml);
if (success == false) {
System.out.println(rest.lastErrorText());
return;
}
// A 200 response is expected for actual success.
if (rest.get_ResponseStatusCode() != 200) {
System.out.println(sbXml.getAsString());
return;
}
// Iterate over the contacts..
boolean bAutoTrim = false;
CkXml xml = new CkXml();
xml.LoadSb(sbXml,bAutoTrim);
xml.SaveXml("qa_cache/xero_contacts.xml");
// How many records exist?
int recordCount = xml.NumChildrenAt("Contacts");
System.out.println("numRecords = " + recordCount);
int i = 0;
while (i < recordCount) {
xml.put_I(i);
System.out.println("ContactID: " + xml.getChildContent("Contacts|Contact[i]|ContactID"));
i = i+1;
}
}
}