Skip to content

Instantly share code, notes, and snippets.

@faermanj
Last active August 29, 2015 14:11
Show Gist options
  • Save faermanj/1b2261909e602c8de9ec to your computer and use it in GitHub Desktop.
Save faermanj/1b2261909e602c8de9ec to your computer and use it in GitHub Desktop.
Reactive S3 File Upload
/*
Hello, this is a first attempt to write a reactive app.
It should deploy a static website to AWS S3.
After creating the bucket, it should put the public bucket policy,
configure the bucket website and upload the files in parallel.
putBucketPolicy
createBucket -> putBucketWebsite
uploadFiles -> upload index.html
-> upload other.html
Here is my shot at it:
*/
var fs = require('fs')
var AWS = require('aws-sdk');
var df = require('dateformat');
var now = new Date();
var nows = df(now,"yyyy-mm-dd-hh-MM-ss")
var rx = require("rx")
var bucketName = "example-" + nows;
console.log('Starting Example '+bucketName);
var s3 = new AWS.S3();
//Create Bucket
var createBucket = rx.Observable.fromNodeCallback(s3.createBucket,s3);
var bucket = createBucket({Bucket: bucketName});
//Put Bucket Website
var putBucketWebsite = rx.Observable.fromNodeCallback(s3.putBucketWebsite,s3);
var website = putBucketWebsite({
Bucket: bucketName,
WebsiteConfiguration : {
IndexDocument : {
Suffix:"index.html"},
ErrorDocument: {
Key: "index.html"}
}
});
//Make the bucket public
var putBucketPolicy = rx.Observable.fromNodeCallback(s3.putBucketPolicy,s3);
var publicPolicy = [
'{',
' "Version":"2012-10-17",',
' "Statement":[{',
' "Sid":"AddPerm",',
' "Effect":"Allow",',
' "Principal": "*",',
' "Action":["s3:GetObject"],',
' "Resource":["arn:aws:s3:::'+bucketName+'/*"',
' ]',
' }',
' ]',
'}'].join('')
var pub = putBucketPolicy({
Bucket: bucketName,
Policy: publicPolicy
});
//File Uploads
var files = ["index.html","other.html"];
var readFile = rx.Observable.fromNodeCallback(fs.readFile,fs)
var uploadFile = rx.Observable.fromNodeCallback(s3.putObject,s3)
var uploadFiles = files.map(function(fileName){
return readFile(fileName).flatMap(function(stream){
return uploadFile({
Bucket: bucketName,
Key:fileName,
Body: stream,
ContentType:"text/html"
});
});
})
//Compose the parallel streams
/*
utBucketPolicy
createBucket -> putBucketWebsite
uploadFiles -> upload index.html
-> upload other.html
*/
var pllUploads = rx.Observable.forkJoin(uploadFiles)
var pllTasks = rx.Observable.forkJoin(pub,website,pllUploads)
var deploy = bucket.flatMap(pllTasks);
//Subscribes to deployment steps
var subscription = deploy.subscribe (
function(x) {console.log(x)},
function(e) {
console.error("Deployment failed")
throw e
},
function() {
console.log("Deployment Completed!");
console.log("curl http://"+bucketName+".s3-website-us-east-1.amazonaws.com/")
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment