CMake reorganization.
[bluesky.git] / bluesky / s3store.c
1 /* Blue Sky: File Systems in the Cloud
2  *
3  * Copyright (C) 2009  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * TODO: Licensing
7  */
8
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <glib.h>
12 #include <string.h>
13
14 #include "bluesky.h"
15 #include "libs3.h"
16
17 /* Interface to Amazon S3 storage. */
18
19 /* Simple in-memory data store for test purposes. */
20 struct S3Store {
21     S3BucketContext bucket;
22 };
23
24 struct S3Store *s3store_new()
25 {
26     struct S3Store *store = g_new(struct S3Store, 1);
27     store->bucket.bucketName = "mvrable-bluesky";
28     store->bucket.protocol = S3ProtocolHTTP;
29     store->bucket.uriStyle = S3UriStylePath;
30     store->bucket.accessKeyId = getenv("AWS_ACCESS_KEY_ID");
31     store->bucket.secretAccessKey = getenv("AWS_SECRET_ACCESS_KEY");
32
33     g_print("Initializing S3 with bucket %s, access key %s\n",
34             store->bucket.bucketName, store->bucket.accessKeyId);
35
36     return store;
37 }
38
39 struct get_info {
40     gchar *buf;
41     gint offset;
42 };
43
44 static S3Status s3store_get_handler(int bufferSize, const char *buffer,
45                                     void *callbackData)
46 {
47     struct get_info *info = (struct get_info *)callbackData;
48     gint bytes = MIN(bufferSize, (int)(BLUESKY_BLOCK_SIZE - info->offset));
49     memcpy(info->buf + info->offset, buffer, bytes);
50     info->offset += bytes;
51     return S3StatusOK;
52 }
53
54 struct put_info {
55     BlueSkyRCStr *val;
56     gint offset;
57 };
58
59 static int s3store_put_handler(int bufferSize, char *buffer,
60                                void *callbackData)
61 {
62     struct put_info *info = (struct put_info *)callbackData;
63     gint bytes = MIN(bufferSize, (int)(info->val->len - info->offset));
64     memcpy(buffer, (char *)info->val->data + info->offset, bytes);
65     info->offset += bytes;
66     return bytes;
67 }
68
69 static S3Status s3store_properties_callback(const S3ResponseProperties *properties,
70                                      void *callbackData)
71 {
72     g_print("(Properties callback)\n");
73     return S3StatusOK;
74 }
75
76 void s3store_response_callback(S3Status status,
77                                const S3ErrorDetails *errorDetails,
78                                void *callbackData)
79 {
80     g_print("S3 operation complete, status=%s\n",
81             S3_get_status_name(status));
82     if (errorDetails != NULL) {
83         g_print("  Error message: %s\n", errorDetails->message);
84     }
85 }
86
87 BlueSkyRCStr *s3store_get(struct S3Store *store, const gchar *key)
88 {
89     struct get_info info;
90     info.buf = (char *)g_malloc0(BLUESKY_BLOCK_SIZE);
91     info.offset = 0;
92
93     struct S3GetObjectHandler handler;
94     handler.responseHandler.propertiesCallback = s3store_properties_callback;
95     handler.responseHandler.completeCallback = s3store_response_callback;
96     handler.getObjectDataCallback = s3store_get_handler;
97
98     g_print("Starting fetch of %s from S3...\n", key);
99     S3_get_object(&store->bucket, key, NULL, 0, 0, NULL,
100                   &handler, &info);
101
102     return bluesky_string_new(info.buf, BLUESKY_BLOCK_SIZE);
103 }
104
105 void s3store_put(struct S3Store *store, const gchar *key, BlueSkyRCStr *val)
106 {
107     struct put_info info;
108     info.val = val;
109     info.offset = 0;
110
111     struct S3PutObjectHandler handler;
112     handler.responseHandler.propertiesCallback = s3store_properties_callback;
113     handler.responseHandler.completeCallback = s3store_response_callback;
114     handler.putObjectDataCallback = s3store_put_handler;
115
116     g_print("Starting store of %s to S3...\n", key);
117     S3_put_object(&store->bucket, key, val->len, NULL, NULL,
118                   &handler, &info);
119 }