Overview:
 
jclouds allows provisioning and control of cloud resources, including blobstore
and compute, from Java and Clojure.  Our API gives allows developers to use
both portable abstractions and cloud-specific features.  We test support of 30
cloud providers and cloud software stacks, including Amazon, Azure, GoGrid,
Ninefold, OpenStack, and vCloud.  jclouds is licensed under the Apache License,
Version 2.0
 
our current version is 1.4.2
our next maintenance version is 1.4.2-SNAPSHOT
our dev version is 1.5.0-SNAPSHOT
 
check out our examples site! https://github.com/jclouds/jclouds-examples

our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
                          cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
                          trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic)
                          cloudsigma-zrh, elasticstack(generic), go2cloud-jhb1, cloudsigma-lvs,
                          bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
                          slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1), 
                          elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
                          openhosting-east1, serverlove-z1-man, skalicloud-sdg-my,
                          greenhousedata-element-vcloud, softlayer, cloudsigma (generic),
                          cloudstack (generic), ninefold-compute, openstack-nov (keystone),
                          hpcloud-compute, trystack-nova, openstack-nova-ec2,
                          rackspace-cloudservers-us (next gen), rackspace-cloudservers-uk (next gen)

  * note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
           to all of these providers

our blobstore api supports: aws-s3, cloudfiles-us, cloudfiles-uk, filesystem,
                            azureblob, atmos (generic), synaptic-storage, hpcloud-objectstorage,
                            cloudonestorage, walrus(generic), ninefold-storage,
                            eucalyptus-partnercloud-s3, swift (generic), transient (in-mem)
 
  * note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
           to all of these providers

our loadbalancer api supports: cloudloadbalancers-us
 
  * note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
           to all of these providers

we also have aws-cloudwatch support.

we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, openstack nova, scality ring,
                          hosteurope-storage, tiscali-storage, scaleup-storage, googlestorage,
                          azurequeue, simpledb, as well as a async-http-client
                          driver in the sandbox


If you want access to all jclouds components, include the maven dependency org.jclouds/jclouds-all


BlobStore Example (Java):
  // init
  context = new BlobStoreContextFactory().createContext(
                  "aws-s3",
                  accesskeyid,
                  secretaccesskey);
  blobStore = context.getBlobStore();
 
  // create container
  blobStore.createContainerInLocation(null, "mycontainer");
  
  // add blob
  blob = blobStore.blobBuilder("test").payload("testdata").build();
  blobStore.putBlob("mycontainer", blob);

BlobStore Example (Clojure):
  (use 'org.jclouds.blobstore2)

  (def *blobstore* (blobstore "azureblob" account encodedkey))
  (create-container *blobstore* "mycontainer")
  (put-blob *blobstore* "mycontainer" (blob "test" :payload "testdata"))

Compute Example (Java):
  // init
  context = new ComputeServiceContextFactory().createContext(
                  "aws-ec2",
                  accesskeyid,
                  secretaccesskey,
                  ImmutableSet.of(new Log4JLoggingModule(),
                                  new SshjSshClientModule()));
  client = context.getComputeService();
 
  // define the requirements of your node
  template = client.templateBuilder().osFamily(UBUNTU).smallest().build();

  // setup a boot user which is the same as your login
  template.getOptions().runScript(AdminAccess.standard());
 
  // these nodes will be accessible via ssh when the call returns
  nodes = client.createNodesInGroup("mycluster", 2, template);

  // you can now run ad-hoc commands on the nodes based on predicates
  responses = client.runScriptOnNodesMatching(inGroup("mycluster"), "uptime",
                  wrapInInitScript(false));

Compute Example (Clojure):
  (use 'org.jclouds.compute2)

  ; create a compute service using sshj and log4j extensions
  (def compute 
    (*compute* "trmk`-ecloud" "user" "password" :sshj :log4j))

  ; launch a couple nodes with the default operating system, installing your user.
  (create-nodes *compute* "mycluster" 2
    (TemplateOptions$Builder/runScript (AdminAccess/standard)))
 
  ; run a command on that group
  (run-script-on-nodes-matching *compute* (in-group? "mycluster") "uptime" 
    (RunScriptOptions$Builder/wrapInInitScript false))

Downloads:
  * release notes: http://www.jclouds.org/documentation/releasenotes/1.3
  * installation guide: http://www.jclouds.org/documentation/userguide/installation-guide
  * maven repo: http://repo2.maven.org/maven2 (maven central - the default repository)
  * snapshot repo: https://oss.sonatype.org/content/repositories/snapshots
 
Links:
  * project page: http://jclouds.org/
  * documentation: http://www.jclouds.org/documentation/index
  * javadocs (1.1.0): http://jclouds.rimuhosting.com/apidocs/
  * javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
  * community: http://www.jclouds.org/documentation/reference/apps-that-use-jclouds
  * user group: http://groups.google.com/group/jclouds
  * dev group: http://groups.google.com/group/jclouds-dev
  * twitter: http://twitter.com/jclouds

## License

Copyright (C) 2009-2012 jclouds, Inc.

Licensed under the Apache License, Version 2.0
