Sample code for 30+ languages & platforms
Java Requires Chilkat v11.0.0+

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

Java
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;
        }
  }
}