Created
March 31, 2016 12:47
-
-
Save mankind/6247224170a664c72aedabc7162a84d5 to your computer and use it in GitHub Desktop.
Getting started aws ses and demo using aws_sdk gem version 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Getting started aws ses | |
http://codechannels.com/video/amazonwebservices/cloud/getting-started-with-amazon-ses/ | |
1. Verify email address | |
In the sandbox you can send email only from emails yiu have verified. | |
Go to email AWS SES then on the left clcik on 'verified senders' | |
to start the verification process: | |
a. click 'verify a ne sender' | |
in the dialogue box add your email and click submit. you will receive | |
an verification email. to verify the email, click the link in the email. | |
b. Go back to aws ses in the aws dashboard and click 'verified senders'. | |
you will see the new verified email. beside it click on 'send test email'. | |
2. Send an email | |
as a new user you will be placed on aws sandbox and will not have unlimited send. | |
in the sandbox, email can be sent only to and from verified email. | |
you can send a maximum of 200 messagesper day. you can send a maximu of one message per second. | |
3. Request production access | |
To request production access, click on request production access. | |
################################ | |
aws-sdk-core gem or version 2 of aws-ruby gem | |
https://www.youtube.com/watch?v=7oyx7dRBwGs | |
at 32 miunte shows how to write a plugin to acts as a middleware to insert in the gem | |
the gem pulls any env variables means for aws like ENV[AWS_REGION'] | |
it ships with aws.rb binary which you can see by typing. | |
it uses pry as an interactive console and fals back to irb | |
aws.rb -h | |
from there you have access to all amazon services | |
aws> AWS::S3.new | |
#to list all the aws services and their classes | |
aws> Aws.service_classes | |
#there are helper methods for creating aws service client | |
aws> Aws.s3 | |
or just type for similar result as above | |
aws> s3 | |
#each service constructor accepts a hash of configuaration parameters | |
aws> s3.config. | |
#it retries failed attempt 3 times by defaut | |
aws> s3.config.retry_limit | |
#you can configure the retry limit with | |
aws> s3(retry_limit: 10).config.retry_limit | |
#make a round trip request to aws dynamo service to see the tables | |
aws> resp = dynamodb.list_tables(limit: 1) | |
#there are some interesting properties on the response object above | |
aws> resp.context | |
#list s3 buckets and map their names | |
aws> resp = s3.list_buckets | |
aws > resp.buckets.first.creation_date | |
aws > resp.buckets.first[:creation_date] | |
aws > resp.to_hash | |
#u can carryout paramter validation, which means if you pass in the wrong paramsters | |
it will fail with the right errors. so the parametsrs for dynamodb believe | |
is missing some values. | |
aws > dynamodb.create_table(table: 'my-table', provisioned_throughput: {read_capacity_units: 9000}) | |
#entering debug mode | |
the command below will return even the wire response that the gem parses | |
#calling aws.rb -v allows wire tracing to see the request made over the wire and the response | |
aws > aws.rb -v | |
aws > s3.list_buckets;nil | |
aws > Aws.s3(http_wire_trace: false) | |
aws > Aws.config[:http_wire_transfer] = false | |
#to exit the aws.rb interactive shell call 'quit' | |
aws > quit | |
#you can scope configuration option to just a service while other service still use the default. | |
aws > Aws.config[:s3] = {retry_limit: 10} | |
aws> Aws.config[:s3][:force_paths] = true | |
aws > Aws.config.delete(:force_paths) | |
#CHECKING AWS api versions | |
#u can check which version service client api you are using but by default | |
you will get the latest api. | |
#let's say you want t work against the 2011 version of an service client api | |
#first check the available api versions with | |
aws > AWS::DynamoDB.api_versions | |
aws > Aws::DynamoDB.new(api_version: '2011-12-05') | |
#set the api version globally for all service | |
aws > Aws.config[:api_version] = '2012-01-01' | |
################################################# | |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
AWS re:Invent 2014 | (DEV303) Touring Version 2 of the AWS SDK for Ruby | |
https://www.youtube.com/watch?v=9-PS5LtLZ9g | |
installing version sdk | |
gem install aws-sdk --pre | |
gem install aws-sdl-resources --pre | |
gem install aws-sdk-core | |
bundleing sdk in your gem file | |
gem 'aws-sdk', '~>2' | |
managing aws credentials | |
-never put aws credentials in source code | |
-credential provider chain | |
-environmental variables, -shared credential file, -EC2 instances profile credential. | |
shared credential file | |
-by default looks in '#{HOME}/.aws/credentials' | |
- INI format | |
- AWS CLI and other SDKs use same credentials | |
- "AWS_PROFILE" specifies credential profile. | |
eg of what credential filelooks like | |
~/.aws/credentials | |
[default] | |
aws_access_key_id = AKEX | |
aws_secret_access_key = fakefoo/bar | |
[prod] | |
aws_access_key_id = AKEX | |
aws_secret_access_key = fakefoo/bar | |
demo in the console | |
aws > s3 = Aws::S3::Resource.new | |
#each resource comes with a client | |
aws > s3.client | |
#we can create an s3 bucket resource object and we haven't made a sytem call yet | |
aws > b = s3.bucket('wizebee-bucket') | |
aws > b.objects | |
aws > b.objects.map(&:key) | |
#the aws gem provides all of the features of ruby enumerable and as with | |
ec2 instances, we can pass in different filters and other parameters | |
you will male into list objects | |
aws > videos = b.objects(prefix: "videos/") | |
#we can also use the enumerable method call reject | |
if we want to get everything but the mp4 file | |
aws > videos.reject { |o|/\.mp4$/ .match(o.key) } | |
#delete all the videos | |
aws > videos.delete | |
amazon s3: iterating objects | |
#involves automatic pagination | |
client = Aws::S3:Client.new | |
resp = client.list_objects(bucket: name) | |
resp.each do |page| | |
puts page.contents.map(&:key) | |
end | |
or use resources to achieve the above | |
s3 = = Aws::S3:Client.new | |
s3.bucket(name).objects.each do |obj| | |
puts obj.key | |
end | |
with the aws-sdk gem version 2 | |
--all rsponses automatically paginated, including client responses | |
- include helper methods | |
- replace many V1 higher level abstractions | |
##waiters in aws-sdk 2 (at 22 minutes) | |
amazon ec2: waiting on an instance to become available | |
client.wait_until(instance_running, instance_ids: [instance_ids]) | |
amazon s3: waiting on an object to exist | |
client.wait_until(:object_exists, bucket: bucket_name, key: object_key) | |
or using resources | |
s3.bucket(bucket_name).object(object_key).wait_until_exists | |
#you can check the waiters name on the client | |
aws > s3.client.waiter_names | |
#lets take a look at an object, wait until it exists and then read the body | |
#this code returns 404 | |
aws > puts b.objects('hello-reivent').wait_until_exists.get.body.read | |
# so lets make it exists | |
aws > s3.bucket('reinvent-ruby-demo').object('hello-reinvent').put(body: 'hello') | |
the waiters aws-sdk version 2 | |
-poll client requests for success/failure states | |
-configurable | |
-can be used with base client and resources | |
ruby on rails example with aws-sdk v2 | |
todo sample app | |
https://github.com/awslabs/todo-sample-app | |
http://ruby.awsblog.com/blog/tag/TodoApp | |
-exceedingly simple task manager | |
feature added during demo(task update notifications feature) | |
-requirement: notify users when tasks states changes | |
-multiple delivery methids eg email and sms | |
-needs to scale, this is going to be big | |
solution: amazon sns integration (at 28 minutes) | |
from page 51 | |
http://www.slideshare.net/AmazonWebServices/dev303-touring-version-2-of-the-aws-sdk-for-ruby-aws-reinvent-2014 | |
-supports email | |
-supports sms | |
-handles saling for you | |
-resources api supports sns | |
in the gemfile | |
gem 'aws-sdk-resources' | |
app/views/tasks/index.html.erb | |
#we add two form tags, one to populate sms and email subscriber each | |
<div id='subscription-forms'> | |
<h3>subscribe to task updates</h3> | |
<div id='sms-form> | |
<p> subscribe via sms</p> | |
<%= form_tag("/subscriptions/sms", method: 'post') do %> | |
<%= telephone_field(:subscription, :endpoint) %> | |
<%= submit_tag('subscribe')%> | |
<% end %> | |
</div> | |
<div id='email-form> | |
<p> subscribe via email</p> | |
<%= form_tag("/subscriptions/email", method: 'post') do %> | |
<%= email_field(:subscription, :endpoint) %> | |
<%= submit_tag('subscribe')%> | |
<% end %> | |
</div> | |
</div> | |
##config/routes.rb | |
post 'subscriptions/sms' => 'subscriptions#create_sms' | |
post 'subscriptions/email' => 'subscriptions#create_email' | |
#create a controller for our subscriptions | |
class SubscriptionsController < ApplicationCcontroller | |
def create_sms | |
subscription.subscribe('sms', params['subscription'['endpoint']) | |
redirect_to task_paths | |
end | |
#email pseudo class and we specify the endpoint and redirect back to our page | |
def create_email | |
subscription.subscribe('email', params['subscription'['endpoint']) | |
redirect_to task_paths | |
end | |
end | |
#the subscription pseudo model | |
#remember when you create a resource call it will not make | |
#a client call until it has to, so we have used that to simplify the code | |
#below by making 3 calls | |
app/models/subscription.rb | |
class Subscription | |
def self.topic | |
#first call related to aws_sdk which creates a topic | |
AWS::SNS::Resource.new.topic(TOPIC_ARN) | |
end | |
def self.subscribe(protocol, endpoint) | |
#second call related to aws_sdk, which creates a subscription | |
topic.subscribe(protocol: protocol, endpoint: endpoint) if topic | |
end | |
def self.publish(message, subject = nil) | |
opts = {message: message} | |
opts[:subject] = subject if subject | |
#third call related to aws_sdk, which publishes a message | |
topics.publish(opts) | |
end | |
end | |
#in the task controller, for each task actions, we want to | |
add a publishing notification with one line subscription.publish | |
app/controller/tasks_controller.rb | |
class TasksController < ApplicationController | |
def create | |
@task = Task.new(task_create_params) | |
if @task.save | |
#publish a notification | |
subscription.publish("created new task: #{@task.name}", "new task created") | |
redirect_to tasks_path | |
else | |
flash[:error] = "task creation failed! #{print_erros(@task)}" | |
redirect_to tasks_path | |
end | |
end | |
end | |
what we did with code implementing the notification feature | |
- every time a tasks is created, updated, or deleted, | |
a status message is published to amazon | |
- amazon sns handles delivery and scaling | |
-eliminatied duplication with resouces apis | |
Miniature Rails app that provides an example of handling SES bounce notifications with a README that describes SES bounce config | |
https://github.com/dondenoncourt/aws_ses_bounce_mini_app | |
https://github.com/Bellwether/The-Swarm/blob/master/app/models/subscription.rb | |
https://github.com/newstrust/SocialNews |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment