javarackspacecloudfilesjclouds

rackspace cloudfiles throws ContainerNotFoundException after migration from jclouds 1.5 to 1.7


I am trying to update the jclouds libs we use from version 1.5 to 1.7.

We access the api the following way: https://github.com/jclouds/jclouds-examples/tree/master/rackspace/src/main/java/org/jclouds/examples/rackspace/cloudfiles

private RestContext<CommonSwiftClient, CommonSwiftAsyncClient> swift;
BlobStoreContext context = ContextBuilder.newBuilder(PROVIDER)
.credentials(username, apiKey)
.buildView(BlobStoreContext.class);

swift = context.unwrap();

RestContext is deprecated since 1.6. http://demobox.github.io/jclouds-maven-site-1.6.0/1.6.0/jclouds-multi/apidocs/org/jclouds/rest/RestContext.html

I tried to get it working this way:

ContextBuilder contextBuilder = ContextBuilder.newBuilder(rackspaceProvider)
.credentials(rackspaceUsername, rackspaceApiKey);
rackspaceApi = contextBuilder.buildApi(CloudFilesClient.class);

At runtime, uploading a file i get the following error:

org.jclouds.blobstore.ContainerNotFoundException

The examples in the jclouds github project seem to use the deprecated approach (Links mentioned above).

Any ideas how to solve this? Any alternatives?


Solution

  • Does the container that you're uploading into exist? The putObject method doesn't automatically create the container that you name if it doesn't exist; you need to call createContainer explicitly to create it, first.

    Here's an example that creates a container and uploads a file into it:

    CloudFilesClient client = ContextBuilder.newBuilder("cloudfiles-us")
        .credentials(USERNAME, APIKEY)
        .buildApi(CloudFilesClient.class);
    
    client.createContainer("sample");
    
    SwiftObject object = client.newSwiftObject();
    object.getInfo().setName("somefile.txt");
    object.setPayload("file or bytearray or something else here");
    client.putObject("sample", object);
    
    // ...
    
    client.close();
    

    You're right that the examples in jclouds-examples still reference RestClient, but you should be able to translate to the new style by substituting your rackspaceApi object where they call swift.getApi().