Krishna

Senior Ruby on Rails Developer.

Cloudfront Private Streaming With Ruby on Rails 3

Please check below steps to setup amazon cloudfront private content streaming in Ruby on Rails 3

Create Amazon s3 bucket to store your private contents

  1. Go to Amazon Simple storage service(S3)

  2. Click ‘create bucket’ button, give bucket name and click ‘create’

  3. Select bucket, click ‘create folder’ on top and give folder name

  4. Add your mp4 contents in newly created folder

Create private streaming distribution in cloudfront

  1. Go to cloud front console

  2. Click ‘create distribution’ button

  3. Select ‘Streaming’ and click ‘continue’

  4. Set below configuration

    • Origin Domain name

      Choose your bucket name in the drop down

    • Restrict Bucket Access

      Select ‘Yes’

    • Origin Access Identity

      Select ‘Create a new identity’ or ‘use an existing identity’ if you already created it

    • Grant Read Permissions on Bucket

      Select ‘Yes, update bucket policy’

    • Restrict Viewer Access (Use signed urls)

      Select ‘yes’

    • Distribution State

      Select ‘Enabled’

  5. Click ‘create distribution’ and go to cloudfront home page

  6. Check the status of your newly created private distribution it shows ‘in progress’, wait until status shows as ‘deployed’, it may take longer time to get deployed

Create cloudfront key pairs

Note: If you already created private key and key pair id skip below steps

  1. Sign in to the AWS management console and go to security credential page at https://portal.aws.amazon.com/gp/aws/securityCredentials.

  2. Under ‘Access credentials’, click the ‘kay pairs’ tab

  3. Under ‘Amazon cloudFront key pairs’, click ‘create a new key pair’

  4. Save private key and store it in safe place

  5. Copy key pair id and paste it somewhere to use it later

Note: These Key pair id and private key required to access the private streaming distribution

Access private streaming in Ruby on Rails

Install https://github.com/krishnasrihari/cloudfront-private gem and configure it as described in guide

Rails 3 Sweepers

Rails 3 sweepers are same as observers but there are small changes for configuration

Create sweeper Directory

Create separate directory name ‘sweepers’ for your application in app directory

Configuration

Add your all sweepers to autooload in config/application.rb

config.autoload_paths += %W(#{config.root}/app/sweepers)

RSpec test case for sweeper

Write test cases for your sweepers

let(:photo) { FactoryGirl.create(:photo) }
    let(:sweeper) { CommentSweeper.instance}

    context "#after save" do
        it "should be called" do
            sweeper.should_receive(:after_save)
            ActiveRecord::Observer.with_observers(:comment_sweeper) do          
                photo.comments.create(:comment =>  "test")
            end         
        end     
    end

Write test case for caching

    context "#after save cache" do
        before do
            Rails.cache.clear
            ActionController::Base.perform_caching = true
            Rails.cache.write("views/photo-#{photo.id}-comments","photo comments content")
        end
        after do
            ActionController::Base.perform_caching = false
        end

        it "should be clear cached content " do         
            ActiveRecord::Observer.with_observers(:comment_sweeper) do          
                photo.comments.create(:comment =>  "update photo comments content")
            end
            Rails.cache.read("views/photo-#{photo.id}-comments").should be_nil
        end     
    end

https://github.com/patmaddox/no-peeping-toms gem required to pass this testcase

Create new sweepers and bind the model to listen

    class CommentSweeper < ActionController::Caching::Sweeper
        observe Comment # Bind to Comment model

        def after_save(comment)
            expire_cache_for(comment)
        end

        def after_destroy(comment)
            expire_cache_for(comment)
        end

        private         
            def expire_cache_for(comment)
                expire_fragment("comment-#{comment.id}")
                Rails.cache.delete("views/photo-#{comment.photo.id}-comments")                  
            end
    end

Add it to controller

class CommentsController < ApplicationController
    cache_sweeper :comment_sweeper, :only => :create

    def create
        ....
    end
end

Once comment#create executed your sweeper expires the fragment cache.

Execute your sweeper test case, it will execute without any error.