Getting started with S3 using Cloudfork
Cloudfork provides access to the REST API of the Amazon S3 Web Service that can be used to store and retrieve any amount of data, at any time, from anywhere on the web.
Two basic concepts of S3 are buckets and objects. Buckets are essentially named containers of S3 objects. An S3 Object refers to data and has a key. To some extent, these concepts are similar to folders and files in a filesystem. Using the S3 service, you can create buckets, put objects in them and get each object using its key. In addition, with S3 you can control the access (public,private) of buckets and objects. This subject will be discussed in another post.
Before using any of the Amazon Web Services, you should have an AWS account and you should sign up for the S3 storage service. Once you have created that account, you can create a Cloudfork AWSCredentials object which is needed for all communication with AWS.
| awsCredentials s3 response bucket result |
awsCredentials := CFAWSCredentials
newWith: '<your access key id>'
andSecret: '<your secret access key>'.
Create a Bucket
Use CFSimpleStorageService to create and delete buckets. Each API message in Cloudfork returns a response object, for this service that will be a CFS3Response. Every response has a result and, in case of an error, detailed information about the reason for failure. You should always inspect the response whether it was successful.
s3 := CFSimpleStorageService newWith: awsCredentials.
response := s3 createBucketNamed: '< your new bucket name >' .
response isError
ifTrue:[self error: 'creation failed because:',
response errorMessageText].
Put an Object
You need a CFBucket object to access objects. Use the service (temporal variable s3) to open one. Now you have a reference (temporal variable bucket) to a service object that can store and retrieve objects in your bucket. Any data (from 1 byte up to 5 GB) that you put in your bucket must have a key (String). Keys must be unique within a bucket.
bucket := s3 openBucketNamed: '< your existing bucket name >'.
response := bucket
putObject: 'Small in the Cloud'
as: 'someKey'.
response isError
ifTrue:[self error: 'storing the object failed because:',
response errorMessageText].
You can also use the Dictionary method at:put: for accessing the bucket. The example above stores a String object in a bucket but any collection of bytes can be stored. For instance, you can also pass in a FileStream as the “put” argument.
Put an Image from File
response := bucket
putObjectAs: 'picture'
readFrom: (FileStream fileNamed: 'picture.jpg')
withHeaders: ((Dictionary new) at: 'Content-Type' put: 'image/jpeg' ;yourself).
response isError
ifTrue:[self error: 'storing the image object failed because:',
response errorMessageText].
In a follow up post, we will discuss best practices in choosing keys for objects. One of them is using the “/” separator character to simulate a filesystem.
The examples below are straightforward. We invite you to write an example that lists all object keys of one of your buckets.
Get an Object
response := bucket
getObject: 'someKey'
writeOn: (result := WriteStream on: ByteArray new).
response isError
ifTrue:[self error: 'access to the object failed because:',
response errorMessageText].
Delete an Object
response := bucket deleteObject: 'someKey'.
response isError
ifTrue:[self error: 'object removal failed because:',
response errorMessageText].
Note: removeKey: can also be used which does not return a CFS3Response.
Delete Bucket
response := s3 deleteBucketNamed: '< your existing bucket name >' .
response isError
ifTrue:[self error: 'delete bucket failed because:',
response errorMessageText].
This post showed you the basic usage of the Cloudfork S3 services. Browse the classes in this package to see how other S3 API services are mapped to Smalltalk messages. Future posts will discuss these in more detail.
January 13, 2009 at 08:13
I can’t seem to get the tests to run in several environments. The method fromPreparedString: doesn’t seem to be included in any of the packages and a Google search doesn’t reveal any clues as to where it may be found.
Will you point me in the right direction for this method?
Thanks!
January 13, 2009 at 16:22
Hello John,
You are right. The method should be part of the Cloudfork-Squeak-Platform package as a class extension. It was left out because we renamed the package. This is fixed in the versions jvds.19. If you load this version or a later version it should work. Thank you for the feedback!